aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-12-04 19:56:40 -0500
committerAlon Zakai <alonzakai@gmail.com>2013-12-04 19:56:40 -0500
commitfa828f4a179f561a872b683ba7ff02fba47b62d2 (patch)
treefd27628f852a4ea4eada50332db1d669e845e137 /lib/Transforms
parent82307b1c5b914e45b400aa5721688714adce18e7 (diff)
begin to legalize i64 sext
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/NaCl/ExpandI64.cpp66
-rw-r--r--lib/Transforms/NaCl/PNaClABISimplify.cpp3
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
}
+