diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-12-04 19:56:40 -0500 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-12-04 19:56:40 -0500 |
commit | fa828f4a179f561a872b683ba7ff02fba47b62d2 (patch) | |
tree | fd27628f852a4ea4eada50332db1d669e845e137 /lib/Transforms | |
parent | 82307b1c5b914e45b400aa5721688714adce18e7 (diff) |
begin to legalize i64 sext
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/NaCl/ExpandI64.cpp | 66 | ||||
-rw-r--r-- | lib/Transforms/NaCl/PNaClABISimplify.cpp | 3 |
2 files changed, 65 insertions, 4 deletions
diff --git a/lib/Transforms/NaCl/ExpandI64.cpp b/lib/Transforms/NaCl/ExpandI64.cpp index 741afbb4e0..8f4bcbd2f3 100644 --- a/lib/Transforms/NaCl/ExpandI64.cpp +++ b/lib/Transforms/NaCl/ExpandI64.cpp @@ -32,12 +32,34 @@ #include "llvm/Pass.h" #include "llvm/Transforms/NaCl.h" +#include "llvm/Support/raw_ostream.h" +#include <stdio.h> +#define dump(x) fprintf(stderr, x "\n") +#define dumpv(x, ...) fprintf(stderr, x "\n", __VA_ARGS__) +#define dumpIR(value) { \ + std::string temp; \ + raw_string_ostream stream(temp); \ + stream << *(value); \ + dumpv("%s\n", temp.c_str()); \ +} + using namespace llvm; namespace { // This is a ModulePass because the pass recreates functions in // order to expand i64 arguments to pairs of i32s. class ExpandI64 : public ModulePass { + typedef std::vector<Value*> SplitParts; + + std::map<Value*, SplitParts> Splits; // old i64 value to new insts + + // splits a 64-bit instruction into 32-bit chunks. We do + // not yet have the values yet, as they depend on other + // splits, so store the parts in Splits, for FinalizeInst. + void SplitInst(Instruction *I); + + void FinalizeInst(Instruction *I); + public: static char ID; ExpandI64() : ModulePass(ID) { @@ -53,16 +75,52 @@ INITIALIZE_PASS(ExpandI64, "expand-i64", "Expand and lower i64 operations into 32-bit chunks", false, false) -static void ExpandI64Func(Function *Func) { -} +//static void ExpandI64Func(Function *Func) { +//} + +void ExpandI64::SplitInst(Instruction *I) { +dumpv("si1 %d %d", I->getOpcode(), Instruction::SExt); + switch (I->getOpcode()) { + case Instruction::SExt: { + Value *Input = I->getOperand(0); + Type *T = Input->getType(); + assert(T->getIntegerBitWidth() == 32); // FIXME: sext from smaller + // x = sext i32 to i64 ==> + // xl = x ; test = x < 0 ; xh = test ? -1 : 0 + Value *Zero = Constant::getNullValue(T); + Value *Ones = Constant::getAllOnesValue(T); + + Value *Check = CopyDebug(new ICmpInst(I, ICmpInst::ICMP_SLE, Input, Zero), I); + Value *High = CopyDebug(SelectInst::Create(Check, Ones, Zero, "", I), I); + SplitParts &Split = Splits[I]; + Split.push_back(Check); + Split.push_back(High); -static void ExpandI64Inst(VAArgInst *Inst) { + break; + } + //default: // FIXME: abort if we hit something we don't support + } } bool ExpandI64::runOnModule(Module &M) { bool Changed = false; DataLayout DL(&M); - + for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E; ) { + Function *Func = Iter++; + for (Function::iterator BB = Func->begin(), E = Func->end(); + BB != E; + ++BB) { + for (BasicBlock::iterator Iter = BB->begin(), E = BB->end(); + Iter != E; ) { + Instruction *I = Iter++; + Type *T = I->getType(); + if (T->isIntegerTy() && T->getIntegerBitWidth() == 64) { + Changed = true; + SplitInst(I); + } + } + } + } return Changed; } diff --git a/lib/Transforms/NaCl/PNaClABISimplify.cpp b/lib/Transforms/NaCl/PNaClABISimplify.cpp index 013c03550d..38d8ae0a40 100644 --- a/lib/Transforms/NaCl/PNaClABISimplify.cpp +++ b/lib/Transforms/NaCl/PNaClABISimplify.cpp @@ -143,4 +143,7 @@ void llvm::PNaClABISimplifyAddPostOptPasses(PassManager &PM) { // created. PM.add(createDeadInstEliminationPass()); PM.add(createDeadCodeEliminationPass()); + + PM.add(createExpandI64Pass()); // EMSCRIPTEN // FIXME: move this before the dce stuff here } + |