OLD | NEW |
1 //===- RewriteAtomics.cpp - Stabilize instructions used for concurrency ---===// | 1 //===- RewriteAtomics.cpp - Stabilize instructions used for concurrency ---===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This pass encodes atomics, volatiles and fences using NaCl intrinsics | 10 // This pass encodes atomics, volatiles and fences using NaCl intrinsics |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 class RewriteAtomics : public ModulePass { | 44 class RewriteAtomics : public ModulePass { |
45 public: | 45 public: |
46 static char ID; // Pass identification, replacement for typeid | 46 static char ID; // Pass identification, replacement for typeid |
47 RewriteAtomics() : ModulePass(ID) { | 47 RewriteAtomics() : ModulePass(ID) { |
48 // This is a module pass because it may have to introduce | 48 // This is a module pass because it may have to introduce |
49 // intrinsic declarations into the module and modify a global function. | 49 // intrinsic declarations into the module and modify a global function. |
50 initializeRewriteAtomicsPass(*PassRegistry::getPassRegistry()); | 50 initializeRewriteAtomicsPass(*PassRegistry::getPassRegistry()); |
51 } | 51 } |
52 | 52 |
53 virtual bool runOnModule(Module &M); | 53 virtual bool runOnModule(Module &M); |
54 virtual void getAnalysisUsage(AnalysisUsage &Info) const { | |
55 Info.addRequired<DataLayoutPass>(); | |
56 } | |
57 }; | 54 }; |
58 | 55 |
59 template <class T> std::string ToStr(const T &V) { | 56 template <class T> std::string ToStr(const T &V) { |
60 std::string S; | 57 std::string S; |
61 raw_string_ostream OS(S); | 58 raw_string_ostream OS(S); |
62 OS << const_cast<T &>(V); | 59 OS << const_cast<T &>(V); |
63 return OS.str(); | 60 return OS.str(); |
64 } | 61 } |
65 | 62 |
66 class AtomicVisitor : public InstVisitor<AtomicVisitor> { | 63 class AtomicVisitor : public InstVisitor<AtomicVisitor> { |
67 public: | 64 public: |
68 AtomicVisitor(Module &M, Pass &P) | 65 AtomicVisitor(Module &M, Pass &P) |
69 : M(M), C(M.getContext()), | 66 : M(M), C(M.getContext()), |
70 TD(P.getAnalysis<DataLayoutPass>().getDataLayout()), AI(C), | 67 TD(M.getDataLayout()), AI(C), |
71 ModifiedModule(false) {} | 68 ModifiedModule(false) {} |
72 ~AtomicVisitor() {} | 69 ~AtomicVisitor() {} |
73 bool modifiedModule() const { return ModifiedModule; } | 70 bool modifiedModule() const { return ModifiedModule; } |
74 | 71 |
75 void visitLoadInst(LoadInst &I); | 72 void visitLoadInst(LoadInst &I); |
76 void visitStoreInst(StoreInst &I); | 73 void visitStoreInst(StoreInst &I); |
77 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I); | 74 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I); |
78 void visitAtomicRMWInst(AtomicRMWInst &I); | 75 void visitAtomicRMWInst(AtomicRMWInst &I); |
79 void visitFenceInst(FenceInst &I); | 76 void visitFenceInst(FenceInst &I); |
80 | 77 |
81 private: | 78 private: |
82 Module &M; | 79 Module &M; |
83 LLVMContext &C; | 80 LLVMContext &C; |
84 const DataLayout TD; | 81 const DataLayout TD; |
85 NaCl::AtomicIntrinsics AI; | 82 NaCl::AtomicIntrinsics AI; |
86 bool ModifiedModule; | 83 bool ModifiedModule; |
87 | 84 |
88 AtomicVisitor() LLVM_DELETED_FUNCTION; | 85 AtomicVisitor() = delete; |
89 AtomicVisitor(const AtomicVisitor &) LLVM_DELETED_FUNCTION; | 86 AtomicVisitor(const AtomicVisitor &) = delete; |
90 AtomicVisitor &operator=(const AtomicVisitor &) LLVM_DELETED_FUNCTION; | 87 AtomicVisitor &operator=(const AtomicVisitor &) = delete; |
91 | 88 |
92 /// Create an integer constant holding a NaCl::MemoryOrder that can be | 89 /// Create an integer constant holding a NaCl::MemoryOrder that can be |
93 /// passed as an argument to one of the @llvm.nacl.atomic.* | 90 /// passed as an argument to one of the @llvm.nacl.atomic.* |
94 /// intrinsics. This function may strengthen the ordering initially | 91 /// intrinsics. This function may strengthen the ordering initially |
95 /// specified by the instruction \p I for stability purpose. | 92 /// specified by the instruction \p I for stability purpose. |
96 template <class Instruction> | 93 template <class Instruction> |
97 ConstantInt *freezeMemoryOrder(const Instruction &I, AtomicOrdering O) const; | 94 ConstantInt *freezeMemoryOrder(const Instruction &I, AtomicOrdering O) const; |
98 std::pair<ConstantInt *, ConstantInt *> | 95 std::pair<ConstantInt *, ConstantInt *> |
99 freezeMemoryOrder(const AtomicCmpXchgInst &I, AtomicOrdering S, | 96 freezeMemoryOrder(const AtomicCmpXchgInst &I, AtomicOrdering S, |
100 AtomicOrdering F) const; | 97 AtomicOrdering F) const; |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 ArrayRef<Value *>()); | 420 ArrayRef<Value *>()); |
424 } else { | 421 } else { |
425 const NaCl::AtomicIntrinsics::AtomicIntrinsic *Intrinsic = | 422 const NaCl::AtomicIntrinsics::AtomicIntrinsic *Intrinsic = |
426 findAtomicIntrinsic(I, Intrinsic::nacl_atomic_fence, T); | 423 findAtomicIntrinsic(I, Intrinsic::nacl_atomic_fence, T); |
427 Value *Args[] = {freezeMemoryOrder(I, I.getOrdering())}; | 424 Value *Args[] = {freezeMemoryOrder(I, I.getOrdering())}; |
428 replaceInstructionWithIntrinsicCall(I, Intrinsic, T, T, Args); | 425 replaceInstructionWithIntrinsicCall(I, Intrinsic, T, T, Args); |
429 } | 426 } |
430 } | 427 } |
431 | 428 |
432 ModulePass *llvm::createRewriteAtomicsPass() { return new RewriteAtomics(); } | 429 ModulePass *llvm::createRewriteAtomicsPass() { return new RewriteAtomics(); } |
OLD | NEW |