Index: lib/Transforms/NaCl/SimplifyAllocas.cpp |
diff --git a/lib/Transforms/NaCl/SimplifyAllocas.cpp b/lib/Transforms/NaCl/SimplifyAllocas.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..906b38606efdce907b7d6fc4c54dafa092adc07f |
--- /dev/null |
+++ b/lib/Transforms/NaCl/SimplifyAllocas.cpp |
@@ -0,0 +1,108 @@ |
+//===- SimplifyAllocas.cpp - Simplify allocas to arrays of bytes --===// |
+// |
+// The LLVM Compiler Infrastructure |
+// |
+// This file is distributed under the University of Illinois Open Source |
+// License. See LICENSE.TXT for details. |
+// |
+//===----------------------------------------------------------------------===// |
+// |
+// Simplify all allocas into allocas of byte arrays. |
+// |
+//===----------------------------------------------------------------------===// |
+ |
+#include "llvm/IR/Constants.h" |
+#include "llvm/IR/DataLayout.h" |
+#include "llvm/IR/Function.h" |
+#include "llvm/IR/Instructions.h" |
+#include "llvm/IR/Module.h" |
+#include "llvm/Transforms/NaCl.h" |
+ |
+using namespace llvm; |
+namespace { |
+class SimplifyAllocas : public BasicBlockPass { |
+public: |
+ static char ID; // Pass identification, replacement for typeid |
+ SimplifyAllocas() |
+ : BasicBlockPass(ID), Initialized(false), M(nullptr), IntPtrType(nullptr), |
+ Int8Type(nullptr), DL(nullptr) { |
+ initializeSimplifyAllocasPass(*PassRegistry::getPassRegistry()); |
+ } |
+ |
+private: |
+ bool Initialized; |
+ const Module *M; |
+ Type *IntPtrType; |
+ Type *Int8Type; |
+ const DataLayout *DL; |
+ |
+ using llvm::Pass::doInitialization; |
+ bool doInitialization(Function &F) override { |
+ if (!Initialized) { |
+ M = F.getParent(); |
+ DL = M->getDataLayout(); |
+ IntPtrType = DL->getIntPtrType(M->getContext()); |
+ Int8Type = Type::getInt8Ty(M->getContext()); |
+ Initialized = true; |
+ return true; |
+ } |
+ return false; |
+ } |
+ |
+ bool runOnBasicBlock(BasicBlock &BB) override { |
+ bool Changed = false; |
+ for (BasicBlock::iterator I = BB.getFirstInsertionPt(), E = BB.end(); |
+ I != E;) { |
+ if (AllocaInst *Alloca = dyn_cast<AllocaInst>(I++)) { |
+ Changed = true; |
+ Type *ElementTy = Alloca->getType()->getPointerElementType(); |
+ Constant *ElementSize = |
+ ConstantInt::get(IntPtrType, DL->getTypeAllocSize(ElementTy)); |
+ // Expand out alloca's built-in multiplication. |
+ Value *MulSize; |
+ if (ConstantInt *C = dyn_cast<ConstantInt>(Alloca->getArraySize())) { |
+ const APInt Value = |
+ C->getValue().zextOrTrunc(IntPtrType->getScalarSizeInBits()); |
+ MulSize = ConstantExpr::getMul(ElementSize, |
+ ConstantInt::get(IntPtrType, Value)); |
+ } else { |
+ Value *ArraySize = Alloca->getArraySize(); |
+ if (ArraySize->getType() != IntPtrType) { |
+ // We assume ArraySize is always positive, and thus is unsigned. |
+ assert(!isa<ConstantInt>(ArraySize) || |
+ !cast<ConstantInt>(ArraySize)->isNegative()); |
+ ArraySize = |
+ CastInst::CreateIntegerCast(ArraySize, IntPtrType, |
+ /* isSigned = */ false, "", Alloca); |
+ } |
+ MulSize = CopyDebug( |
+ BinaryOperator::Create(Instruction::Mul, ElementSize, ArraySize, |
+ Alloca->getName() + ".alloca_mul", Alloca), |
+ Alloca); |
+ } |
+ unsigned Alignment = Alloca->getAlignment(); |
+ if (Alignment == 0) |
+ Alignment = DL->getPrefTypeAlignment(ElementTy); |
+ AllocaInst *Tmp = |
+ new AllocaInst(Int8Type, MulSize, Alignment, "", Alloca); |
+ CopyDebug(Tmp, Alloca); |
+ Tmp->takeName(Alloca); |
+ BitCastInst *BC = new BitCastInst(Tmp, Alloca->getType(), |
+ Tmp->getName() + ".bc", Alloca); |
+ CopyDebug(BC, Alloca); |
+ Alloca->replaceAllUsesWith(BC); |
+ Alloca->eraseFromParent(); |
+ } |
+ } |
+ return Changed; |
+ } |
+}; |
+} |
+char SimplifyAllocas::ID = 0; |
+ |
+INITIALIZE_PASS(SimplifyAllocas, "simplify-allocas", |
+ "Simplify allocas to arrays of bytes", false, false) |
+ |
+BasicBlockPass *llvm::createSimplifyAllocasPass() { |
+ return new SimplifyAllocas(); |
+} |