[arm-fast-isel] Add support for non-global callee.

Patch by Jush Lu <jush.msn@gmail.com>.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157336 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chad Rosier
2012-05-23 18:38:57 +00:00
parent 2b52630094
commit 1c8fccbc12
2 changed files with 37 additions and 7 deletions

View File

@@ -2216,11 +2216,6 @@ bool ARMFastISel::SelectCall(const Instruction *I,
// Can't handle inline asm. // Can't handle inline asm.
if (isa<InlineAsm>(Callee)) return false; if (isa<InlineAsm>(Callee)) return false;
// Only handle global variable Callees.
const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
if (!GV)
return false;
// Check the calling convention. // Check the calling convention.
ImmutableCallSite CS(CI); ImmutableCallSite CS(CI);
CallingConv::ID CC = CS.getCallingConv(); CallingConv::ID CC = CS.getCallingConv();
@@ -2313,18 +2308,33 @@ bool ARMFastISel::SelectCall(const Instruction *I,
// Issue the call. // Issue the call.
MachineInstrBuilder MIB; MachineInstrBuilder MIB;
const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
unsigned CallOpc = ARMSelectCallOp(GV); unsigned CallOpc = ARMSelectCallOp(GV);
unsigned CalleeReg = 0;
if (!GV){
CallOpc = isThumb2 ? ARM::tBLXr : ARM::BLX;
CalleeReg = getRegForValue(Callee);
if (CalleeReg == 0) return false;
}
// Explicitly adding the predicate here. // Explicitly adding the predicate here.
if(isThumb2) { if(isThumb2) {
// Explicitly adding the predicate here. // Explicitly adding the predicate here.
MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(CallOpc))); TII.get(CallOpc)));
if (!IntrMemName) if (!GV)
MIB.addReg(CalleeReg);
else if (!IntrMemName)
MIB.addGlobalAddress(GV, 0, 0); MIB.addGlobalAddress(GV, 0, 0);
else else
MIB.addExternalSymbol(IntrMemName, 0); MIB.addExternalSymbol(IntrMemName, 0);
} else { } else {
if (!IntrMemName) if (!GV)
MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(CallOpc))
.addReg(CalleeReg));
else if (!IntrMemName)
// Explicitly adding the predicate here. // Explicitly adding the predicate here.
MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, MIB = AddDefaultPred(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
TII.get(CallOpc)) TII.get(CallOpc))

View File

@@ -126,3 +126,23 @@ entry:
} }
declare i32 @bar(i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext) declare i32 @bar(i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext)
define i32 @bar0(i32 %i) nounwind {
ret i32 0
}
define void @foo3() uwtable {
; ARM: movw r0, #0
; ARM: movw r1, :lower16:_bar0
; ARM: movt r1, :upper16:_bar0
; ARM: blx r1
; THUMB: movs r0, #0
; THUMB: movw r1, :lower16:_bar0
; THUMB: movt r1, :upper16:_bar0
; THUMB: blx r1
%fptr = alloca i32 (i32)*, align 8
store i32 (i32)* @bar0, i32 (i32)** %fptr, align 8
%1 = load i32 (i32)** %fptr, align 8
%call = call i32 %1(i32 0)
ret void
}