summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2015-04-22 06:02:31 +0000
committerLang Hames <lhames@gmail.com>2015-04-22 06:02:31 +0000
commit65613a634aa0ca9824b22259bd6b7cd97314e504 (patch)
tree1a3a2b375262964901c8c888fb4f15cc0f79db9b /llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
parent1f429e49269442bb31fa03ef93a808cf72e4d32b (diff)
downloadbcm5719-llvm-65613a634aa0ca9824b22259bd6b7cd97314e504.tar.gz
bcm5719-llvm-65613a634aa0ca9824b22259bd6b7cd97314e504.zip
[patchpoint] Add support for symbolic patchpoint targets to SelectionDAG and the
X86 backend. The code generated for symbolic targets is identical to the code generated for constant targets, except that a relocation is emitted to fix up the actual target address at link-time. This allows IR and object files containing patchpoints to be cached across JIT-invocations where the target address may change. llvm-svn: 235483
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/FastISel.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/FastISel.cpp28
1 files changed, 15 insertions, 13 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index dafbc63dbd0..2b624adac94 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -711,7 +711,7 @@ bool FastISel::selectPatchpoint(const CallInst *I) {
CallingConv::ID CC = I->getCallingConv();
bool IsAnyRegCC = CC == CallingConv::AnyReg;
bool HasDef = !I->getType()->isVoidTy();
- Value *Callee = I->getOperand(PatchPointOpers::TargetPos);
+ Value *Callee = I->getOperand(PatchPointOpers::TargetPos)->stripPointerCasts();
// Get the real number of arguments participating in the call <numArgs>
assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::NArgPos)) &&
@@ -757,23 +757,25 @@ bool FastISel::selectPatchpoint(const CallInst *I) {
cast<ConstantInt>(I->getOperand(PatchPointOpers::NBytesPos));
Ops.push_back(MachineOperand::CreateImm(NumBytes->getZExtValue()));
- // Assume that the callee is a constant address or null pointer.
- // FIXME: handle function symbols in the future.
- uint64_t CalleeAddr;
- if (const auto *C = dyn_cast<IntToPtrInst>(Callee))
- CalleeAddr = cast<ConstantInt>(C->getOperand(0))->getZExtValue();
- else if (const auto *C = dyn_cast<ConstantExpr>(Callee)) {
- if (C->getOpcode() == Instruction::IntToPtr)
- CalleeAddr = cast<ConstantInt>(C->getOperand(0))->getZExtValue();
- else
+ // Add the call target.
+ if (const auto *C = dyn_cast<IntToPtrInst>(Callee)) {
+ uint64_t CalleeConstAddr =
+ cast<ConstantInt>(C->getOperand(0))->getZExtValue();
+ Ops.push_back(MachineOperand::CreateImm(CalleeConstAddr));
+ } else if (const auto *C = dyn_cast<ConstantExpr>(Callee)) {
+ if (C->getOpcode() == Instruction::IntToPtr) {
+ uint64_t CalleeConstAddr =
+ cast<ConstantInt>(C->getOperand(0))->getZExtValue();
+ Ops.push_back(MachineOperand::CreateImm(CalleeConstAddr));
+ } else
llvm_unreachable("Unsupported ConstantExpr.");
+ } else if (const auto *GV = dyn_cast<GlobalValue>(Callee)) {
+ Ops.push_back(MachineOperand::CreateGA(GV, 0));
} else if (isa<ConstantPointerNull>(Callee))
- CalleeAddr = 0;
+ Ops.push_back(MachineOperand::CreateImm(0));
else
llvm_unreachable("Unsupported callee address.");
- Ops.push_back(MachineOperand::CreateImm(CalleeAddr));
-
// Adjust <numArgs> to account for any arguments that have been passed on
// the stack instead.
unsigned NumCallRegArgs = IsAnyRegCC ? NumArgs : CLI.OutRegs.size();
OpenPOWER on IntegriCloud