diff options
Diffstat (limited to 'contrib/llvm/lib/Transforms/Scalar/LowerAtomic.cpp')
-rw-r--r-- | contrib/llvm/lib/Transforms/Scalar/LowerAtomic.cpp | 146 |
1 files changed, 62 insertions, 84 deletions
diff --git a/contrib/llvm/lib/Transforms/Scalar/LowerAtomic.cpp b/contrib/llvm/lib/Transforms/Scalar/LowerAtomic.cpp index 973ffe7..9087b46 100644 --- a/contrib/llvm/lib/Transforms/Scalar/LowerAtomic.cpp +++ b/contrib/llvm/lib/Transforms/Scalar/LowerAtomic.cpp @@ -14,26 +14,15 @@ #define DEBUG_TYPE "loweratomic" #include "llvm/Transforms/Scalar.h" -#include "llvm/BasicBlock.h" #include "llvm/Function.h" -#include "llvm/Instruction.h" -#include "llvm/Instructions.h" -#include "llvm/Intrinsics.h" +#include "llvm/IntrinsicInst.h" #include "llvm/Pass.h" #include "llvm/Support/IRBuilder.h" - using namespace llvm; -namespace { - -bool LowerAtomicIntrinsic(CallInst *CI) { - IRBuilder<> Builder(CI->getParent(), CI); - - Function *Callee = CI->getCalledFunction(); - if (!Callee) - return false; - - unsigned IID = Callee->getIntrinsicID(); +static bool LowerAtomicIntrinsic(IntrinsicInst *II) { + IRBuilder<> Builder(II->getParent(), II); + unsigned IID = II->getIntrinsicID(); switch (IID) { case Intrinsic::memory_barrier: break; @@ -48,80 +37,70 @@ bool LowerAtomicIntrinsic(CallInst *CI) { case Intrinsic::atomic_load_min: case Intrinsic::atomic_load_umax: case Intrinsic::atomic_load_umin: { - Value *Ptr = CI->getArgOperand(0); - Value *Delta = CI->getArgOperand(1); + Value *Ptr = II->getArgOperand(0), *Delta = II->getArgOperand(1); LoadInst *Orig = Builder.CreateLoad(Ptr); Value *Res = NULL; switch (IID) { - default: assert(0 && "Unrecognized atomic modify operation"); - case Intrinsic::atomic_load_add: - Res = Builder.CreateAdd(Orig, Delta); - break; - case Intrinsic::atomic_load_sub: - Res = Builder.CreateSub(Orig, Delta); - break; - case Intrinsic::atomic_load_and: - Res = Builder.CreateAnd(Orig, Delta); - break; - case Intrinsic::atomic_load_nand: - Res = Builder.CreateNot(Builder.CreateAnd(Orig, Delta)); - break; - case Intrinsic::atomic_load_or: - Res = Builder.CreateOr(Orig, Delta); - break; - case Intrinsic::atomic_load_xor: - Res = Builder.CreateXor(Orig, Delta); - break; - case Intrinsic::atomic_load_max: - Res = Builder.CreateSelect(Builder.CreateICmpSLT(Orig, Delta), - Delta, - Orig); - break; - case Intrinsic::atomic_load_min: - Res = Builder.CreateSelect(Builder.CreateICmpSLT(Orig, Delta), - Orig, - Delta); - break; - case Intrinsic::atomic_load_umax: - Res = Builder.CreateSelect(Builder.CreateICmpULT(Orig, Delta), - Delta, - Orig); - break; - case Intrinsic::atomic_load_umin: - Res = Builder.CreateSelect(Builder.CreateICmpULT(Orig, Delta), - Orig, - Delta); - break; + default: assert(0 && "Unrecognized atomic modify operation"); + case Intrinsic::atomic_load_add: + Res = Builder.CreateAdd(Orig, Delta); + break; + case Intrinsic::atomic_load_sub: + Res = Builder.CreateSub(Orig, Delta); + break; + case Intrinsic::atomic_load_and: + Res = Builder.CreateAnd(Orig, Delta); + break; + case Intrinsic::atomic_load_nand: + Res = Builder.CreateNot(Builder.CreateAnd(Orig, Delta)); + break; + case Intrinsic::atomic_load_or: + Res = Builder.CreateOr(Orig, Delta); + break; + case Intrinsic::atomic_load_xor: + Res = Builder.CreateXor(Orig, Delta); + break; + case Intrinsic::atomic_load_max: + Res = Builder.CreateSelect(Builder.CreateICmpSLT(Orig, Delta), + Delta, Orig); + break; + case Intrinsic::atomic_load_min: + Res = Builder.CreateSelect(Builder.CreateICmpSLT(Orig, Delta), + Orig, Delta); + break; + case Intrinsic::atomic_load_umax: + Res = Builder.CreateSelect(Builder.CreateICmpULT(Orig, Delta), + Delta, Orig); + break; + case Intrinsic::atomic_load_umin: + Res = Builder.CreateSelect(Builder.CreateICmpULT(Orig, Delta), + Orig, Delta); + break; } Builder.CreateStore(Res, Ptr); - CI->replaceAllUsesWith(Orig); + II->replaceAllUsesWith(Orig); break; } case Intrinsic::atomic_swap: { - Value *Ptr = CI->getArgOperand(0); - Value *Val = CI->getArgOperand(1); - + Value *Ptr = II->getArgOperand(0), *Val = II->getArgOperand(1); LoadInst *Orig = Builder.CreateLoad(Ptr); Builder.CreateStore(Val, Ptr); - - CI->replaceAllUsesWith(Orig); + II->replaceAllUsesWith(Orig); break; } case Intrinsic::atomic_cmp_swap: { - Value *Ptr = CI->getArgOperand(0); - Value *Cmp = CI->getArgOperand(1); - Value *Val = CI->getArgOperand(2); + Value *Ptr = II->getArgOperand(0), *Cmp = II->getArgOperand(1); + Value *Val = II->getArgOperand(2); LoadInst *Orig = Builder.CreateLoad(Ptr); Value *Equal = Builder.CreateICmpEQ(Orig, Cmp); Value *Res = Builder.CreateSelect(Equal, Val, Orig); Builder.CreateStore(Res, Ptr); - - CI->replaceAllUsesWith(Orig); + II->replaceAllUsesWith(Orig); break; } @@ -129,33 +108,32 @@ bool LowerAtomicIntrinsic(CallInst *CI) { return false; } - assert(CI->use_empty() && + assert(II->use_empty() && "Lowering should have eliminated any uses of the intrinsic call!"); - CI->eraseFromParent(); + II->eraseFromParent(); return true; } -struct LowerAtomic : public BasicBlockPass { - static char ID; - LowerAtomic() : BasicBlockPass(ID) {} - bool runOnBasicBlock(BasicBlock &BB) { - bool Changed = false; - for (BasicBlock::iterator DI = BB.begin(), DE = BB.end(); DI != DE; ) { - Instruction *Inst = DI++; - if (CallInst *CI = dyn_cast<CallInst>(Inst)) - Changed |= LowerAtomicIntrinsic(CI); +namespace { + struct LowerAtomic : public BasicBlockPass { + static char ID; + LowerAtomic() : BasicBlockPass(ID) { + initializeLowerAtomicPass(*PassRegistry::getPassRegistry()); } - return Changed; - } - -}; - + bool runOnBasicBlock(BasicBlock &BB) { + bool Changed = false; + for (BasicBlock::iterator DI = BB.begin(), DE = BB.end(); DI != DE; ) + if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(DI++)) + Changed |= LowerAtomicIntrinsic(II); + return Changed; + } + }; } char LowerAtomic::ID = 0; INITIALIZE_PASS(LowerAtomic, "loweratomic", "Lower atomic intrinsics to non-atomic form", - false, false); + false, false) Pass *llvm::createLowerAtomicPass() { return new LowerAtomic(); } |