diff options
author | Dan Gohman <sunfish@google.com> | 2014-02-13 19:24:56 -0800 |
---|---|---|
committer | Dan Gohman <sunfish@google.com> | 2014-02-14 11:38:16 -0800 |
commit | 71fb6dcb87d2abd302080149d4a583a5e35e3697 (patch) | |
tree | 8fd196d2d2b3ddad6188d72dbfc481395f620d19 /lib | |
parent | f3359807242e95f9e94bb35c0d90a73c794f1af0 (diff) |
Preserve alignment information when promoting integer loads and stores.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/NaCl/PromoteIntegers.cpp | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/lib/Transforms/NaCl/PromoteIntegers.cpp b/lib/Transforms/NaCl/PromoteIntegers.cpp index d48bdfc37b..b8050b5ba2 100644 --- a/lib/Transforms/NaCl/PromoteIntegers.cpp +++ b/lib/Transforms/NaCl/PromoteIntegers.cpp @@ -43,13 +43,25 @@ using namespace llvm; namespace { +class ConversionState; + class PromoteIntegers : public FunctionPass { + DataLayout *DL; + + Value *splitLoad(LoadInst *Inst, ConversionState &State); + Value *splitStore(StoreInst *Inst, ConversionState &State); + void convertInstruction(Instruction *Inst, ConversionState &State); + public: static char ID; PromoteIntegers() : FunctionPass(ID) { initializePromoteIntegersPass(*PassRegistry::getPassRegistry()); } virtual bool runOnFunction(Function &F); + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired<DataLayout>(); + return FunctionPass::getAnalysisUsage(AU); + } }; } @@ -135,6 +147,8 @@ static Value *convertConstant(Constant *C, bool SignExt=false) { } } +namespace { + // Holds the state for converting/replacing values. Conversion is done in one // pass, with each value requiring conversion possibly having two stages. When // an instruction needs to be replaced (i.e. it has illegal operands or result) @@ -212,9 +226,11 @@ class ConversionState { SmallVector<Instruction *, 8> ToErase; }; +} // anonymous namespace + // Split an illegal load into multiple legal loads and return the resulting // promoted value. The size of the load is assumed to be a multiple of 8. -static Value *splitLoad(LoadInst *Inst, ConversionState &State) { +Value *PromoteIntegers::splitLoad(LoadInst *Inst, ConversionState &State) { if (Inst->isVolatile() || Inst->isAtomic()) report_fatal_error("Can't split volatile/atomic loads"); if (cast<IntegerType>(Inst->getType())->getBitWidth() % 8 != 0) @@ -246,7 +262,15 @@ static Value *splitLoad(LoadInst *Inst, ConversionState &State) { HiType->getPointerTo(), OrigPtr->getName() + ".hity"); - Value *LoadHi = IRB.CreateAlignedLoad(BCHi, 1, Inst->getName() + ".hi"); // XXX EMSCRIPTEN: worst-case alignment assumption +#if 0 // XXX EMSCRIPTEN: We want the full-strength alignment. + Value *LoadHi = IRB.CreateAlignedLoad(BCHi, 1, Inst->getName() + ".hi"); +#else + unsigned HiAlign = MinAlign(Inst->getAlignment() == 0 ? + DL->getABITypeAlignment(Inst->getType()) : + Inst->getAlignment(), + LoWidth / 8); + Value *LoadHi = IRB.CreateAlignedLoad(BCHi, HiAlign, Inst->getName() + ".hi"); +#endif if (!isLegalSize(Width - LoWidth)) { LoadHi = splitLoad(cast<LoadInst>(LoadHi), State); #if 0 /// XXX EMSCRIPTEN: We don't need to convert pointers. @@ -266,7 +290,7 @@ static Value *splitLoad(LoadInst *Inst, ConversionState &State) { return Result; } -static Value *splitStore(StoreInst *Inst, ConversionState &State) { +Value *PromoteIntegers::splitStore(StoreInst *Inst, ConversionState &State) { if (Inst->isVolatile() || Inst->isAtomic()) report_fatal_error("Can't split volatile/atomic stores"); if (cast<IntegerType>(Inst->getValueOperand()->getType())->getBitWidth() % 8 @@ -305,7 +329,15 @@ static Value *splitStore(StoreInst *Inst, ConversionState &State) { HiType->getPointerTo(), OrigPtr->getName() + ".hity"); - Value *StoreHi = IRB.CreateAlignedStore(HiTrunc, BCHi, 1); // XXX EMSCRIPTEN: worst-case alignment assumption +#if 0 // XXX EMSCRIPTEN: We want the full-strength alignment. + Value *StoreHi = IRB.CreateAlignedStore(HiTrunc, BCHi, 1); +#else + unsigned HiAlign = MinAlign(Inst->getAlignment() == 0 ? + DL->getABITypeAlignment(Inst->getValueOperand()->getType()) : + Inst->getAlignment(), + LoWidth / 8); + Value *StoreHi = IRB.CreateAlignedStore(HiTrunc, BCHi, HiAlign); +#endif if (!isLegalSize(Width - LoWidth)) { // HiTrunc is still illegal, and is redundant with the truncate in the @@ -389,7 +421,7 @@ static Value *getSignExtend(Value *Operand, Value *OrigOperand, InsertPt), Shl); } -static void convertInstruction(Instruction *Inst, ConversionState &State) { +void PromoteIntegers::convertInstruction(Instruction *Inst, ConversionState &State) { if (SExtInst *Sext = dyn_cast<SExtInst>(Inst)) { Value *Op = Sext->getOperand(0); Value *NewInst = NULL; @@ -642,6 +674,7 @@ static void convertInstruction(Instruction *Inst, ConversionState &State) { } bool PromoteIntegers::runOnFunction(Function &F) { + DL = &getAnalysis<DataLayout>(); // Don't support changing the function arguments. This should not be // generated by clang. for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { |