aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDan Gohman <sunfish@google.com>2014-02-13 19:24:56 -0800
committerDan Gohman <sunfish@google.com>2014-02-14 11:38:16 -0800
commit71fb6dcb87d2abd302080149d4a583a5e35e3697 (patch)
tree8fd196d2d2b3ddad6188d72dbfc481395f620d19 /lib
parentf3359807242e95f9e94bb35c0d90a73c794f1af0 (diff)
Preserve alignment information when promoting integer loads and stores.
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/NaCl/PromoteIntegers.cpp43
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) {