| 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 |