aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gohman <sunfish@google.com>2014-02-13 18:43:37 -0800
committerDan Gohman <sunfish@google.com>2014-02-14 11:00:47 -0800
commita8eadb7743e528ebac52835c7bd95d722bd3c751 (patch)
tree9915f932cfc9ddefd54f70407783b78ceac4a30c
parent35c77715ea2991eaf0b433ec48d9e43ec54c0269 (diff)
Handle pointer types and ConstantExprs in more places.
-rw-r--r--lib/Target/JSBackend/CallHandlers.h28
-rw-r--r--lib/Target/JSBackend/JSBackend.cpp16
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()) {