OLD | NEW |
1 //===- SimplifyAllocas.cpp - Simplify allocas to arrays of bytes --===// | 1 //===- SimplifyAllocas.cpp - Simplify allocas to arrays of bytes --===// |
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 // Simplify all allocas into allocas of byte arrays. | 10 // Simplify all allocas into allocas of byte arrays. |
11 // | 11 // |
12 //===----------------------------------------------------------------------===// | 12 //===----------------------------------------------------------------------===// |
13 | 13 |
14 #include "llvm/IR/Constants.h" | 14 #include "llvm/IR/Constants.h" |
15 #include "llvm/IR/DataLayout.h" | 15 #include "llvm/IR/DataLayout.h" |
16 #include "llvm/IR/Function.h" | 16 #include "llvm/IR/Function.h" |
17 #include "llvm/IR/Instructions.h" | 17 #include "llvm/IR/Instructions.h" |
18 #include "llvm/IR/IntrinsicInst.h" | 18 #include "llvm/IR/IntrinsicInst.h" |
19 #include "llvm/IR/Module.h" | 19 #include "llvm/IR/Module.h" |
20 #include "llvm/Transforms/NaCl.h" | 20 #include "llvm/Transforms/NaCl.h" |
| 21 #include "llvm/Support/Debug.h" |
21 #include "llvm/Support/raw_ostream.h" | 22 #include "llvm/Support/raw_ostream.h" |
| 23 |
22 using namespace llvm; | 24 using namespace llvm; |
23 namespace { | 25 namespace { |
24 class SimplifyAllocas : public BasicBlockPass { | 26 class SimplifyAllocas : public BasicBlockPass { |
25 public: | 27 public: |
26 static char ID; // Pass identification, replacement for typeid | 28 static char ID; // Pass identification, replacement for typeid |
27 SimplifyAllocas() | 29 SimplifyAllocas() |
28 : BasicBlockPass(ID), Initialized(false), M(nullptr), IntPtrType(nullptr), | 30 : BasicBlockPass(ID), Initialized(false), M(nullptr), IntPtrType(nullptr), |
29 Int8Type(nullptr), DL(nullptr) { | 31 Int8Type(nullptr), DL(nullptr) { |
30 initializeSimplifyAllocasPass(*PassRegistry::getPassRegistry()); | 32 initializeSimplifyAllocasPass(*PassRegistry::getPassRegistry()); |
31 } | 33 } |
(...skipping 11 matching lines...) Expand all Loading... |
43 M = F.getParent(); | 45 M = F.getParent(); |
44 DL = &M->getDataLayout(); | 46 DL = &M->getDataLayout(); |
45 IntPtrType = DL->getIntPtrType(M->getContext()); | 47 IntPtrType = DL->getIntPtrType(M->getContext()); |
46 Int8Type = Type::getInt8Ty(M->getContext()); | 48 Int8Type = Type::getInt8Ty(M->getContext()); |
47 Initialized = true; | 49 Initialized = true; |
48 return true; | 50 return true; |
49 } | 51 } |
50 return false; | 52 return false; |
51 } | 53 } |
52 | 54 |
| 55 AllocaInst *findAllocaFromBC(BitCastInst *BCInst) { |
| 56 Value *Op0 = BCInst->getOperand(0); |
| 57 while (!llvm::isa<AllocaInst>(Op0)) { |
| 58 if (auto *NextBC = llvm::dyn_cast<BitCastInst>(Op0)) { |
| 59 Op0 = NextBC->getOperand(0); |
| 60 } else { |
| 61 dbgs() << "findAllocaFromBC encountered a non-bitcast intermediate val " |
| 62 << *Op0 << " starting w/ BCInst " << *BCInst << "\n"; |
| 63 report_fatal_error( |
| 64 "findAllocaFromBC encountered a non-bitcast intermediate"); |
| 65 } |
| 66 } |
| 67 return llvm::cast<AllocaInst>(Op0); |
| 68 } |
| 69 |
53 bool runOnBasicBlock(BasicBlock &BB) override { | 70 bool runOnBasicBlock(BasicBlock &BB) override { |
54 bool Changed = false; | 71 bool Changed = false; |
55 for (BasicBlock::iterator I = BB.getFirstInsertionPt(), E = BB.end(); | 72 for (BasicBlock::iterator I = BB.getFirstInsertionPt(), E = BB.end(); |
56 I != E;) { | 73 I != E;) { |
57 Instruction *Inst = &*I++; | 74 Instruction *Inst = &*I++; |
58 if (AllocaInst *Alloca = dyn_cast<AllocaInst>(Inst)) { | 75 if (AllocaInst *Alloca = dyn_cast<AllocaInst>(Inst)) { |
59 Changed = true; | 76 Changed = true; |
60 Type *ElementTy = Alloca->getType()->getPointerElementType(); | 77 Type *ElementTy = Alloca->getType()->getPointerElementType(); |
61 Constant *ElementSize = | 78 Constant *ElementSize = |
62 ConstantInt::get(IntPtrType, DL->getTypeAllocSize(ElementTy)); | 79 ConstantInt::get(IntPtrType, DL->getTypeAllocSize(ElementTy)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 if (Call->getIntrinsicID() == Intrinsic::dbg_declare) { | 116 if (Call->getIntrinsicID() == Intrinsic::dbg_declare) { |
100 // dbg.declare's first argument is a special metadata that wraps a | 117 // dbg.declare's first argument is a special metadata that wraps a |
101 // value, and RAUW works on those. It is supposed to refer to the | 118 // value, and RAUW works on those. It is supposed to refer to the |
102 // alloca that represents the variable's storage, but the alloca | 119 // alloca that represents the variable's storage, but the alloca |
103 // simplification may have RAUWed it to use the bitcast. | 120 // simplification may have RAUWed it to use the bitcast. |
104 // Fix it up here by recreating the metadata to use the new alloca. | 121 // Fix it up here by recreating the metadata to use the new alloca. |
105 auto *MV = cast<MetadataAsValue>(Call->getArgOperand(0)); | 122 auto *MV = cast<MetadataAsValue>(Call->getArgOperand(0)); |
106 // Sometimes dbg.declare points to an argument instead of an alloca. | 123 // Sometimes dbg.declare points to an argument instead of an alloca. |
107 if (auto *VM = dyn_cast<ValueAsMetadata>(MV->getMetadata())) { | 124 if (auto *VM = dyn_cast<ValueAsMetadata>(MV->getMetadata())) { |
108 if (auto *BCInst = dyn_cast<BitCastInst>(VM->getValue())) { | 125 if (auto *BCInst = dyn_cast<BitCastInst>(VM->getValue())) { |
109 Value *CastSrc = BCInst->getOperand(0); | 126 AllocaInst *Alloca = findAllocaFromBC(BCInst); |
110 assert(isa<AllocaInst>(CastSrc)); | |
111 Call->setArgOperand( | 127 Call->setArgOperand( |
112 0, | 128 0, |
113 MetadataAsValue::get(Inst->getContext(), | 129 MetadataAsValue::get(Inst->getContext(), |
114 ValueAsMetadata::get(CastSrc))); | 130 ValueAsMetadata::get(Alloca))); |
115 Changed = true; | 131 Changed = true; |
116 } | 132 } |
117 } | 133 } |
118 } | 134 } |
119 } | 135 } |
120 } | 136 } |
121 return Changed; | 137 return Changed; |
122 } | 138 } |
123 }; | 139 }; |
124 } | 140 } |
125 char SimplifyAllocas::ID = 0; | 141 char SimplifyAllocas::ID = 0; |
126 | 142 |
127 INITIALIZE_PASS(SimplifyAllocas, "simplify-allocas", | 143 INITIALIZE_PASS(SimplifyAllocas, "simplify-allocas", |
128 "Simplify allocas to arrays of bytes", false, false) | 144 "Simplify allocas to arrays of bytes", false, false) |
129 | 145 |
130 BasicBlockPass *llvm::createSimplifyAllocasPass() { | 146 BasicBlockPass *llvm::createSimplifyAllocasPass() { |
131 return new SimplifyAllocas(); | 147 return new SimplifyAllocas(); |
132 } | 148 } |
OLD | NEW |