aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
diff options
context:
space:
mode:
authorPhilip Reames <preames@rivosinc.com>2023-03-14 08:39:19 -0700
committerPhilip Reames <listmail@philipreames.com>2023-03-14 10:38:02 -0700
commit9227f286acd8f411b74908b4f1a42a0d748b5cac (patch)
treed9eed0afcf1818f053aaa2c1fc19dab302921ec9 /llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
parentf52c9500b426d249d083b747a70865e2a7190763 (diff)
downloadllvm-9227f286acd8f411b74908b4f1a42a0d748b5cac.zip
llvm-9227f286acd8f411b74908b4f1a42a0d748b5cac.tar.gz
llvm-9227f286acd8f411b74908b4f1a42a0d748b5cac.tar.bz2
Move utility for acting on each lane of ElementCount to common code [nfc]
This was first written for AddressSanitizer, but I'm about to reuse it for MemorySanitizer as well.
Diffstat (limited to 'llvm/lib/Transforms/Utils/BasicBlockUtils.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/BasicBlockUtils.cpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
index 0dd3857..2d1be2c 100644
--- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
+++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
@@ -32,6 +32,7 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
@@ -1599,6 +1600,61 @@ void llvm::SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
}
}
+/// Insert a for (int i = 0; i < End; i++) loop structure (with the exception
+/// that \p End is assumed > 0, and thus not checked on entry) at \p
+/// SplitBefore. Returns the first insert point in the loop body, and the
+/// PHINode for the induction variable (i.e. "i" above).
+static std::pair<Instruction*, Value*>
+SplitBlockAndInsertSimpleForLoop(Value *End, Instruction *SplitBefore) {
+ BasicBlock *LoopPred = SplitBefore->getParent();
+ BasicBlock *LoopBody = SplitBlock(SplitBefore->getParent(), SplitBefore);
+ BasicBlock *LoopExit = SplitBlock(SplitBefore->getParent(), SplitBefore);
+
+ auto *Ty = End->getType();
+ auto &DL = SplitBefore->getModule()->getDataLayout();
+ const unsigned Bitwidth = DL.getTypeSizeInBits(Ty);
+
+ IRBuilder<> Builder(LoopBody->getTerminator());
+ auto *IV = Builder.CreatePHI(Ty, 2, "iv");
+ auto *IVNext =
+ Builder.CreateAdd(IV, ConstantInt::get(Ty, 1), IV->getName() + ".next",
+ /*HasNUW=*/true, /*HasNSW=*/Bitwidth != 2);
+ auto *IVCheck = Builder.CreateICmpEQ(IVNext, End,
+ IV->getName() + ".check");
+ Builder.CreateCondBr(IVCheck, LoopExit, LoopBody);
+ LoopBody->getTerminator()->eraseFromParent();
+
+ // Populate the IV PHI.
+ IV->addIncoming(ConstantInt::get(Ty, 0), LoopPred);
+ IV->addIncoming(IVNext, LoopBody);
+
+ return std::make_pair(LoopBody->getFirstNonPHI(), IV);
+}
+
+void llvm::SplitBlockAndInsertForEachLane(ElementCount EC,
+ Type *IndexTy, Instruction *InsertBefore,
+ std::function<void(IRBuilderBase&, Value*)> Func) {
+
+ IRBuilder<> IRB(InsertBefore);
+
+ if (EC.isScalable()) {
+ Value *NumElements = IRB.CreateElementCount(IndexTy, EC);
+
+ auto [BodyIP, Index] =
+ SplitBlockAndInsertSimpleForLoop(NumElements, InsertBefore);
+
+ IRB.SetInsertPoint(BodyIP);
+ Func(IRB, Index);
+ return;
+ }
+
+ unsigned Num = EC.getFixedValue();
+ for (unsigned Idx = 0; Idx < Num; ++Idx) {
+ IRB.SetInsertPoint(InsertBefore);
+ Func(IRB, ConstantInt::get(IndexTy, Idx));
+ }
+}
+
BranchInst *llvm::GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
BasicBlock *&IfFalse) {
PHINode *SomePHI = dyn_cast<PHINode>(BB->begin());