aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/X86
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2010-07-07 19:20:32 +0000
committerDan Gohman <gohman@apple.com>2010-07-07 19:20:32 +0000
commit4df83ed159f21fdf73a57729c3e9d8c9fcd73607 (patch)
treeabee7270365c3f2f5299e810db3d44482dae9504 /lib/Target/X86
parentf423a69839c4810b890f8a8b09fb8cfbd6bf0139 (diff)
downloadexternal_llvm-4df83ed159f21fdf73a57729c3e9d8c9fcd73607.zip
external_llvm-4df83ed159f21fdf73a57729c3e9d8c9fcd73607.tar.gz
external_llvm-4df83ed159f21fdf73a57729c3e9d8c9fcd73607.tar.bz2
Implement bottom-up fast-isel. This has the advantage of not requiring
a separate DCE pass over MachineInstrs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107804 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86')
-rw-r--r--lib/Target/X86/X86FastISel.cpp64
1 files changed, 42 insertions, 22 deletions
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index 594ca4b..8300715 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -108,6 +108,7 @@ private:
bool X86SelectCall(const Instruction *I);
CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool isTailCall = false);
+ CCAssignFn *CCAssignFnForRet(CallingConv::ID CC, bool isTailCall = false);
const X86InstrInfo *getInstrInfo() const {
return getTargetMachine()->getInstrInfo();
@@ -181,6 +182,20 @@ CCAssignFn *X86FastISel::CCAssignFnForCall(CallingConv::ID CC,
return CC_X86_32_C;
}
+/// CCAssignFnForRet - Selects the correct CCAssignFn for a given calling
+/// convention.
+CCAssignFn *X86FastISel::CCAssignFnForRet(CallingConv::ID CC,
+ bool isTaillCall) {
+ if (Subtarget->is64Bit()) {
+ if (Subtarget->isTargetWin64())
+ return RetCC_X86_Win64_C;
+ else
+ return RetCC_X86_64_C;
+ }
+
+ return RetCC_X86_32_C;
+}
+
/// X86FastEmitLoad - Emit a machine instruction to load a value of type VT.
/// The address is either pre-computed, i.e. Ptr, or a GlobalAddress, i.e. GV.
/// Return true and the result register by reference if it is possible.
@@ -689,34 +704,39 @@ bool X86FastISel::X86SelectRet(const Instruction *I) {
if (F.isVarArg())
return false;
- SmallVector<ISD::OutputArg, 4> Outs;
- GetReturnInfo(F.getReturnType(), F.getAttributes().getRetAttributes(),
- Outs, TLI);
+ if (Ret->getNumOperands() > 0) {
+ SmallVector<ISD::OutputArg, 4> Outs;
+ GetReturnInfo(F.getReturnType(), F.getAttributes().getRetAttributes(),
+ Outs, TLI);
- // Analyze operands of the call, assigning locations to each operand.
- SmallVector<CCValAssign, 16> ValLocs;
- CCState CCInfo(CC, F.isVarArg(), TM, ValLocs, I->getContext());
- CCInfo.AnalyzeReturn(Outs, CCAssignFnForCall(CC));
+ // Analyze operands of the call, assigning locations to each operand.
+ SmallVector<CCValAssign, 16> ValLocs;
+ CCState CCInfo(CC, F.isVarArg(), TM, ValLocs, I->getContext());
+ CCInfo.AnalyzeReturn(Outs, CCAssignFnForRet(CC));
- // Copy the return value into registers.
- for (unsigned i = 0, e = ValLocs.size(); i != e; ++i) {
- CCValAssign &VA = ValLocs[i];
-
- // Don't bother handling odd stuff for now.
- if (VA.getLocInfo() != CCValAssign::Full)
- return false;
- if (!VA.isRegLoc())
+ const Value *RV = Ret->getOperand(0);
+ unsigned Reg = getRegForValue(RV);
+ if (Reg == 0)
return false;
- const Value *RV = Ret->getOperand(VA.getValNo());
- unsigned Reg = getRegForValue(RV);
+ // Copy the return value into registers.
+ for (unsigned i = 0, e = ValLocs.size(); i != e; ++i) {
+ CCValAssign &VA = ValLocs[i];
+
+ // Don't bother handling odd stuff for now.
+ if (VA.getLocInfo() != CCValAssign::Full)
+ return false;
+ if (!VA.isRegLoc())
+ return false;
- TargetRegisterClass* RC = TLI.getRegClassFor(VA.getValVT());
- bool Emitted = TII.copyRegToReg(*FuncInfo.MBB, FuncInfo.InsertPt,
- VA.getLocReg(), Reg, RC, RC, DL);
- assert(Emitted && "Failed to emit a copy instruction!"); Emitted=Emitted;
+ TargetRegisterClass* RC = TLI.getRegClassFor(VA.getValVT());
+ bool Emitted = TII.copyRegToReg(*FuncInfo.MBB, FuncInfo.InsertPt,
+ VA.getLocReg(), Reg + VA.getValNo(),
+ RC, RC, DL);
+ assert(Emitted && "Failed to emit a copy instruction!"); Emitted=Emitted;
- MRI.addLiveOut(X86::XMM0);
+ MRI.addLiveOut(VA.getLocReg());
+ }
}
// Now emit the RET.