aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorDan Gohman <sunfish@google.com>2014-02-24 08:49:19 -0800
committerDan Gohman <sunfish@google.com>2014-02-25 11:58:56 -0800
commit338da97ed47659b9ef04f60067f84cafc93e3dd3 (patch)
tree2a80c78435712eafe02ea4afdc96c8d7713016cb /lib/Transforms
parent5653eb58d0b0068f0ef341c8928aa06d1d0ea3f7 (diff)
Support GEP and ConstantExprs directly in the JSBackend.
This patch also lays the groundwork for the single-use instruction trick to reduce the number of temporary variables.
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/NaCl/ExpandI64.cpp55
-rw-r--r--lib/Transforms/NaCl/ExpandVarArgs.cpp11
-rw-r--r--lib/Transforms/NaCl/LowerEmExceptionsPass.cpp16
-rw-r--r--lib/Transforms/NaCl/PNaClABISimplify.cpp4
-rw-r--r--lib/Transforms/NaCl/PromoteIntegers.cpp10
5 files changed, 68 insertions, 28 deletions
diff --git a/lib/Transforms/NaCl/ExpandI64.cpp b/lib/Transforms/NaCl/ExpandI64.cpp
index a4fbb8c709..911060ebfc 100644
--- a/lib/Transforms/NaCl/ExpandI64.cpp
+++ b/lib/Transforms/NaCl/ExpandI64.cpp
@@ -28,6 +28,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
@@ -37,6 +38,7 @@
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
+#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Transforms/NaCl.h"
#include "llvm/Transforms/Utils/Local.h"
#include <map>
@@ -302,6 +304,23 @@ bool ExpandI64::splitInst(Instruction *I) {
ChunksVec &Chunks = Splits[I];
switch (I->getOpcode()) {
+ case Instruction::GetElementPtr: {
+ GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
+ SmallVector<Value*, 2> NewOps;
+ for (unsigned i = 1, e = I->getNumOperands(); i != e; ++i) {
+ Value *Op = I->getOperand(i);
+ if (isIllegal(Op->getType())) {
+ // Truncate the operand down to one chunk.
+ NewOps.push_back(getChunks(Op)[0]);
+ } else {
+ NewOps.push_back(Op);
+ }
+ }
+ Value *NewGEP = CopyDebug(GetElementPtrInst::Create(GEP->getPointerOperand(), NewOps, "", GEP), GEP);
+ Chunks.push_back(NewGEP);
+ I->replaceAllUsesWith(NewGEP);
+ break;
+ }
case Instruction::SExt: {
ChunksVec InputChunks;
Value *Op = I->getOperand(0);
@@ -881,32 +900,32 @@ bool ExpandI64::splitInst(Instruction *I) {
ChunksVec ExpandI64::getChunks(Value *V) {
assert(isIllegal(V->getType()));
+ unsigned Num = getNumChunks(V->getType());
Type *i32 = Type::getInt32Ty(V->getContext());
- Value *Zero = ConstantInt::get(i32, 0);
- unsigned Num = getNumChunks(V->getType());
+ if (isa<UndefValue>(V))
+ return ChunksVec(Num, UndefValue::get(i32));
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
- APInt C = CI->getValue();
- ChunksVec Chunks;
- for (unsigned i = 0; i < Num; i++) {
- Chunks.push_back(ConstantInt::get(i32, C.trunc(32)));
- C = C.lshr(32);
- }
- return Chunks;
- } else if (Instruction *I = dyn_cast<Instruction>(V)) {
- assert(Splits.find(I) != Splits.end());
- return Splits[I];
- } else if (isa<UndefValue>(V)) {
+ if (Constant *C = dyn_cast<Constant>(V)) {
ChunksVec Chunks;
for (unsigned i = 0; i < Num; i++) {
- Chunks.push_back(Zero);
+ Constant *Count = ConstantInt::get(C->getType(), i * 32);
+ Constant *NewC = ConstantExpr::getTrunc(ConstantExpr::getLShr(C, Count), i32);
+ TargetLibraryInfo *TLI = 0; // TODO
+ if (ConstantExpr *NewCE = dyn_cast<ConstantExpr>(NewC)) {
+ if (Constant *FoldedC = ConstantFoldConstantExpression(NewCE, DL, TLI)) {
+ NewC = FoldedC;
+ }
+ }
+
+ Chunks.push_back(NewC);
}
return Chunks;
- } else {
- assert(Splits.find(V) != Splits.end());
- return Splits[V];
}
+
+ assert(Splits.find(V) != Splits.end());
+ assert(Splits[V].size() == Num);
+ return Splits[V];
}
void ExpandI64::ensureFuncs() {
diff --git a/lib/Transforms/NaCl/ExpandVarArgs.cpp b/lib/Transforms/NaCl/ExpandVarArgs.cpp
index 99c200c9f0..1b605b79ee 100644
--- a/lib/Transforms/NaCl/ExpandVarArgs.cpp
+++ b/lib/Transforms/NaCl/ExpandVarArgs.cpp
@@ -283,9 +283,14 @@ static bool ExpandVarArgCall(InstType *Call, DataLayout *DL) {
ArgTypes.push_back(VarArgsTy->getPointerTo());
FunctionType *NFTy = FunctionType::get(FuncType->getReturnType(),
ArgTypes, false);
- Value *CastFunc =
- CopyDebug(new BitCastInst(Call->getCalledValue(), NFTy->getPointerTo(),
- "vararg_func", Call), Call);
+ /// XXX EMSCRIPTEN: Handle Constants as well as Instructions, since we
+ /// don't run the ConstantExpr lowering pass.
+ Value *CastFunc;
+ if (Constant *C = dyn_cast<Constant>(Call->getCalledValue()))
+ CastFunc = ConstantExpr::getBitCast(C, NFTy->getPointerTo());
+ else
+ CastFunc = CopyDebug(new BitCastInst(Call->getCalledValue(), NFTy->getPointerTo(),
+ "vararg_func", Call), Call);
// Create the converted function call.
FixedArgs.push_back(Buf);
diff --git a/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp b/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp
index a562588c3a..2e3f0924cc 100644
--- a/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp
+++ b/lib/Transforms/NaCl/LowerEmExceptionsPass.cpp
@@ -231,7 +231,21 @@ bool LowerEmExceptions::runOnModule(Module &M) {
unsigned Num = LP->getNumClauses();
SmallVector<Value*,16> NewLPArgs;
NewLPArgs.push_back(LP->getPersonalityFn());
- for (unsigned i = 0; i < Num; i++) NewLPArgs.push_back(LP->getClause(i));
+ for (unsigned i = 0; i < Num; i++) {
+ Value *Arg = LP->getClause(i);
+ // As a temporary workaround for the lack of aggregate varargs support
+ // in the varargs lowering code, break out filter operands into their
+ // component elements.
+ if (LP->isFilter(i)) {
+ ArrayType *ATy = cast<ArrayType>(Arg->getType());
+ for (unsigned elem = 0, elemEnd = ATy->getNumElements(); elem != elemEnd; ++elem) {
+ Instruction *EE = ExtractValueInst::Create(Arg, makeArrayRef(elem), "", LP);
+ NewLPArgs.push_back(EE);
+ }
+ } else {
+ NewLPArgs.push_back(Arg);
+ }
+ }
NewLPArgs.push_back(LP->isCleanup() ? ConstantInt::getTrue(i1) : ConstantInt::getFalse(i1));
CallInst *NewLP = CallInst::Create(LandingPad, NewLPArgs, "", LP);
diff --git a/lib/Transforms/NaCl/PNaClABISimplify.cpp b/lib/Transforms/NaCl/PNaClABISimplify.cpp
index 520663152a..416c38dd17 100644
--- a/lib/Transforms/NaCl/PNaClABISimplify.cpp
+++ b/lib/Transforms/NaCl/PNaClABISimplify.cpp
@@ -116,15 +116,19 @@ void llvm::PNaClABISimplifyAddPostOptPasses(PassManager &PM) {
// are expanded out later.
PM.add(createFlattenGlobalsPass());
+#if 0 // XXX EMSCRIPTEN: We can handle ConstantExprs in our backend.
// We should not place arbitrary passes after ExpandConstantExpr
// because they might reintroduce ConstantExprs.
PM.add(createExpandConstantExprPass());
+#endif
// PromoteIntegersPass does not handle constexprs and creates GEPs,
// so it goes between those passes.
PM.add(createPromoteIntegersPass());
+#if 0 // XXX EMSCRIPTEN: We can handle GEPs in our backend.
// ExpandGetElementPtr must follow ExpandConstantExpr to expand the
// getelementptr instructions it creates.
PM.add(createExpandGetElementPtrPass());
+#endif
// Rewrite atomic and volatile instructions with intrinsic calls.
#if 0 // EMSCRIPTEN: we don't need to fix volatiles etc, and can use llvm intrinsics
PM.add(createRewriteAtomicsPass());
diff --git a/lib/Transforms/NaCl/PromoteIntegers.cpp b/lib/Transforms/NaCl/PromoteIntegers.cpp
index b8050b5ba2..af34faa7e5 100644
--- a/lib/Transforms/NaCl/PromoteIntegers.cpp
+++ b/lib/Transforms/NaCl/PromoteIntegers.cpp
@@ -233,14 +233,14 @@ class ConversionState {
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)
+ if (DL->getTypeSizeInBits(Inst->getType()) % 8 != 0)
report_fatal_error("Loads must be a multiple of 8 bits");
Value *OrigPtr = State.getConverted(Inst->getPointerOperand());
// OrigPtr is a placeholder in recursive calls, and so has no name
if (OrigPtr->getName().empty())
OrigPtr->setName(Inst->getPointerOperand()->getName());
- unsigned Width = cast<IntegerType>(Inst->getType())->getBitWidth();
+ unsigned Width = DL->getTypeSizeInBits(Inst->getType());
Type *NewType = getPromotedType(Inst->getType());
unsigned LoWidth = Width;
@@ -293,8 +293,7 @@ Value *PromoteIntegers::splitLoad(LoadInst *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
- != 0)
+ if (DL->getTypeSizeInBits(Inst->getValueOperand()->getType()) % 8 != 0)
report_fatal_error("Stores must be a multiple of 8 bits");
Value *OrigPtr = State.getConverted(Inst->getPointerOperand());
@@ -302,8 +301,7 @@ Value *PromoteIntegers::splitStore(StoreInst *Inst, ConversionState &State) {
if (OrigPtr->getName().empty())
OrigPtr->setName(Inst->getPointerOperand()->getName());
Value *OrigVal = State.getConverted(Inst->getValueOperand());
- unsigned Width = cast<IntegerType>(
- Inst->getValueOperand()->getType())->getBitWidth();
+ unsigned Width = DL->getTypeSizeInBits(Inst->getValueOperand()->getType());
unsigned LoWidth = Width;
while (!isLegalSize(LoWidth)) LoWidth -= 8;