diff options
author | Dan Gohman <sunfish@google.com> | 2014-02-13 18:43:37 -0800 |
---|---|---|
committer | Dan Gohman <sunfish@google.com> | 2014-02-14 11:00:47 -0800 |
commit | a8eadb7743e528ebac52835c7bd95d722bd3c751 (patch) | |
tree | 9915f932cfc9ddefd54f70407783b78ceac4a30c /lib | |
parent | 35c77715ea2991eaf0b433ec48d9e43ec54c0269 (diff) |
Handle pointer types and ConstantExprs in more places.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/JSBackend/CallHandlers.h | 28 | ||||
-rw-r--r-- | lib/Target/JSBackend/JSBackend.cpp | 16 |
2 files changed, 19 insertions, 25 deletions
diff --git a/lib/Target/JSBackend/CallHandlers.h b/lib/Target/JSBackend/CallHandlers.h index e88b781cb4..4a57bcddc2 100644 --- a/lib/Target/JSBackend/CallHandlers.h +++ b/lib/Target/JSBackend/CallHandlers.h @@ -10,28 +10,18 @@ CallHandlerMap *CallHandlers; // Definitions unsigned getNumArgOperands(const Instruction *I) { - if (const CallInst *CI = dyn_cast<const CallInst>(I)) { - return CI->getNumArgOperands(); - } else { - return cast<const InvokeInst>(I)->getNumArgOperands(); - } + return ImmutableCallSite(I).arg_size(); } const Value *getActuallyCalledValue(const Instruction *I) { - const Value *CV = NULL; - if (const CallInst *CI = dyn_cast<const CallInst>(I)) { - CV = CI->getCalledValue(); - } else { - CV = cast<const InvokeInst>(I)->getCalledValue(); - } - if (const BitCastInst *B = dyn_cast<const BitCastInst>(CV)) { - // if the called value is a bitcast of a function, then we just call it directly, properly - // for example, extern void x() in C will turn into void x(...) in LLVM IR, then the IR bitcasts - // it to the proper form right before the call. this both causes an unnecessary indirect - // call, and it is done with the wrong type. TODO: don't even put it into the function table - if (const Function *F = dyn_cast<const Function>(B->getOperand(0))) { - CV = F; - } + const Value *CV = ImmutableCallSite(I).getCalledValue(); + + // if the called value is a bitcast of a function, then we just call it directly, properly + // for example, extern void x() in C will turn into void x(...) in LLVM IR, then the IR bitcasts + // it to the proper form right before the call. this both causes an unnecessary indirect + // call, and it is done with the wrong type. TODO: don't even put it into the function table + if (const Function *F = dyn_cast<const Function>(CV->stripPointerCasts())) { + CV = F; } return CV; } diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp index fa6c999a7a..ea642163e3 100644 --- a/lib/Target/JSBackend/JSBackend.cpp +++ b/lib/Target/JSBackend/JSBackend.cpp @@ -30,6 +30,7 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Pass.h" #include "llvm/PassManager.h" +#include "llvm/Support/CallSite.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" @@ -303,7 +304,7 @@ namespace { } std::string getPtrAsStr(const Value* Ptr) { Ptr = Ptr->stripPointerCasts(); - if (isa<const ConstantPointerNull>(Ptr)) return "0"; + if (isa<const ConstantPointerNull>(Ptr) || isa<UndefValue>(Ptr)) return "0"; if (const Function *F = dyn_cast<Function>(Ptr)) { return utostr(getFunctionIndex(F)); } else if (const Constant *CV = dyn_cast<Constant>(Ptr)) { @@ -619,7 +620,7 @@ std::string JSWriter::getLoad(const Instruction *I, const Value *P, Type *T, uns break; } case 4: { - if (T->isIntegerTy()) { + if (T->isIntegerTy() || T->isPointerTy()) { switch (Alignment) { case 2: { text = Assign + "HEAPU16[" + PS + ">>1]|" + @@ -636,6 +637,7 @@ std::string JSWriter::getLoad(const Instruction *I, const Value *P, Type *T, uns default: assert(0 && "bad 4i store"); } } else { // float + assert(T->isFloatingPointTy()); switch (Alignment) { case 2: { text = "HEAP16[tempDoublePtr>>1]=HEAP16[" + PS + ">>1]" + sep + @@ -713,7 +715,7 @@ std::string JSWriter::getStore(const Instruction *I, const Value *P, Type *T, co break; } case 4: { - if (T->isIntegerTy()) { + if (T->isIntegerTy() || T->isPointerTy()) { switch (Alignment) { case 2: { text = "HEAP16[" + PS + ">>1]=" + VS + "&65535;" + @@ -730,6 +732,7 @@ std::string JSWriter::getStore(const Instruction *I, const Value *P, Type *T, co default: assert(0 && "bad 4i store"); } } else { // float + assert(T->isFloatingPointTy()); text = "HEAPF32[tempDoublePtr>>2]=" + VS + ';'; switch (Alignment) { case 2: { @@ -795,9 +798,10 @@ std::string JSWriter::getPtrUse(const Value* Ptr) { default: llvm_unreachable("Unsupported type"); case 8: return "HEAPF64[" + utostr(Addr >> 3) + "]"; case 4: { - if (t->isIntegerTy()) { + if (t->isIntegerTy() || t->isPointerTy()) { return "HEAP32[" + utostr(Addr >> 2) + "]"; } else { + assert(t->isFloatingPointTy()); return "HEAPF32[" + utostr(Addr >> 2) + "]"; } } @@ -805,7 +809,7 @@ std::string JSWriter::getPtrUse(const Value* Ptr) { case 1: return "HEAP8[" + utostr(Addr) + "]"; } } else { - return getHeapAccess(getPtrAsStr(Ptr), Bytes, t->isIntegerTy()); + return getHeapAccess(getPtrAsStr(Ptr), Bytes, t->isIntegerTy() || t->isPointerTy()); } } @@ -884,7 +888,7 @@ std::string JSWriter::getConstant(const Constant* CV, AsmCast sign) { } return CI->getValue().toString(10, sign != ASM_UNSIGNED); } else if (isa<UndefValue>(CV)) { - return CV->getType()->isIntegerTy() ? "0" : getCast("0", CV->getType()); + return CV->getType()->isIntegerTy() || CV->getType()->isPointerTy() ? "0" : getCast("0", CV->getType()); } else if (isa<ConstantAggregateZero>(CV)) { if (VectorType *VT = dyn_cast<VectorType>(CV->getType())) { if (VT->getElementType()->isIntegerTy()) { |