| Index: lib/Transforms/NaCl/SimplifyAllocas.cpp
|
| diff --git a/lib/Transforms/NaCl/SimplifyAllocas.cpp b/lib/Transforms/NaCl/SimplifyAllocas.cpp
|
| index 906b38606efdce907b7d6fc4c54dafa092adc07f..ba25b5f961ad5ca28254e67de200b003bb2558e8 100644
|
| --- a/lib/Transforms/NaCl/SimplifyAllocas.cpp
|
| +++ b/lib/Transforms/NaCl/SimplifyAllocas.cpp
|
| @@ -15,9 +15,10 @@
|
| #include "llvm/IR/DataLayout.h"
|
| #include "llvm/IR/Function.h"
|
| #include "llvm/IR/Instructions.h"
|
| +#include "llvm/IR/IntrinsicInst.h"
|
| #include "llvm/IR/Module.h"
|
| #include "llvm/Transforms/NaCl.h"
|
| -
|
| +#include "llvm/Support/raw_ostream.h"
|
| using namespace llvm;
|
| namespace {
|
| class SimplifyAllocas : public BasicBlockPass {
|
| @@ -40,7 +41,7 @@ private:
|
| bool doInitialization(Function &F) override {
|
| if (!Initialized) {
|
| M = F.getParent();
|
| - DL = M->getDataLayout();
|
| + DL = &M->getDataLayout();
|
| IntPtrType = DL->getIntPtrType(M->getContext());
|
| Int8Type = Type::getInt8Ty(M->getContext());
|
| Initialized = true;
|
| @@ -53,7 +54,8 @@ private:
|
| bool Changed = false;
|
| for (BasicBlock::iterator I = BB.getFirstInsertionPt(), E = BB.end();
|
| I != E;) {
|
| - if (AllocaInst *Alloca = dyn_cast<AllocaInst>(I++)) {
|
| + Instruction *Inst = &*I++;
|
| + if (AllocaInst *Alloca = dyn_cast<AllocaInst>(Inst)) {
|
| Changed = true;
|
| Type *ElementTy = Alloca->getType()->getPointerElementType();
|
| Constant *ElementSize =
|
| @@ -93,6 +95,28 @@ private:
|
| Alloca->replaceAllUsesWith(BC);
|
| Alloca->eraseFromParent();
|
| }
|
| + else if (auto *Call = dyn_cast<IntrinsicInst>(Inst)) {
|
| + if (Call->getIntrinsicID() == Intrinsic::dbg_declare) {
|
| + // dbg.declare's first argument is a special metadata that wraps a
|
| + // value, and RAUW works on those. It is supposed to refer to the
|
| + // alloca that represents the variable's storage, but the alloca
|
| + // simplification may have RAUWed it to use the bitcast.
|
| + // Fix it up here by recreating the metadata to use the new alloca.
|
| + auto *MV = cast<MetadataAsValue>(Call->getArgOperand(0));
|
| + // Sometimes dbg.declare points to an argument instead of an alloca.
|
| + if (auto *VM = dyn_cast<ValueAsMetadata>(MV->getMetadata())) {
|
| + if (auto *BCInst = dyn_cast<BitCastInst>(VM->getValue())) {
|
| + Value *CastSrc = BCInst->getOperand(0);
|
| + assert(isa<AllocaInst>(CastSrc));
|
| + Call->setArgOperand(
|
| + 0,
|
| + MetadataAsValue::get(Inst->getContext(),
|
| + ValueAsMetadata::get(CastSrc)));
|
| + Changed = true;
|
| + }
|
| + }
|
| + }
|
| + }
|
| }
|
| return Changed;
|
| }
|
|
|