summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2005-04-04 22:17:48 +0000
committerNate Begeman <natebegeman@mac.com>2005-04-04 22:17:48 +0000
commit119453105779eb7817a910024a48e947b4713eba (patch)
treea9a4412c7f0f2313a014aaa567b0d90e652539b6 /llvm/lib/Target
parentc7186025deff868abdf3a0ea9ee215024a81dfef (diff)
downloadbcm5719-llvm-119453105779eb7817a910024a48e947b4713eba.tar.gz
bcm5719-llvm-119453105779eb7817a910024a48e947b4713eba.zip
Make sure that arg regs used by the call instruction are marked as such, so
that regalloc doesn't cleverly reuse early arg regs loading later arg regs. This fixes almost all outstanding failures in the pattern isel. llvm-svn: 21086
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp40
1 files changed, 25 insertions, 15 deletions
diff --git a/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp b/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
index 8751f421f7f..dfd2d549252 100644
--- a/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
+++ b/llvm/lib/Target/PowerPC/PPC32ISelPattern.cpp
@@ -1069,6 +1069,24 @@ unsigned ISel::SelectExpr(SDOperand N) {
Select(N.getOperand(0));
ExprMap[N.getValue(Node->getNumValues()-1)] = 1;
+ MachineInstr *CallMI;
+ // Emit the correct call instruction based on the type of symbol called.
+ if (GlobalAddressSDNode *GASD =
+ dyn_cast<GlobalAddressSDNode>(N.getOperand(1))) {
+ CallMI = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(),
+ true);
+ } else if (ExternalSymbolSDNode *ESSDN =
+ dyn_cast<ExternalSymbolSDNode>(N.getOperand(1))) {
+ CallMI = BuildMI(PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(),
+ true);
+ } else {
+ Tmp1 = SelectExpr(N.getOperand(1));
+ BuildMI(BB, PPC::OR, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1);
+ BuildMI(BB, PPC::MTCTR, 1).addReg(PPC::R12);
+ CallMI = BuildMI(PPC::CALLindirect, 3).addImm(20).addImm(0)
+ .addReg(PPC::R12);
+ }
+
// Load the register args to virtual regs
std::vector<unsigned> ArgVR;
for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
@@ -1083,32 +1101,24 @@ unsigned ISel::SelectExpr(SDOperand N) {
case MVT::i16:
case MVT::i32:
assert(GPR_idx < 8 && "Too many int args");
- if (N.getOperand(i+2).getOpcode() != ISD::UNDEF)
+ if (N.getOperand(i+2).getOpcode() != ISD::UNDEF) {
BuildMI(BB, PPC::OR,2,GPR[GPR_idx]).addReg(ArgVR[i]).addReg(ArgVR[i]);
+ CallMI->addRegOperand(GPR[GPR_idx], MachineOperand::Use);
+ }
++GPR_idx;
break;
case MVT::f64:
case MVT::f32:
assert(FPR_idx < 13 && "Too many fp args");
BuildMI(BB, PPC::FMR, 1, FPR[FPR_idx]).addReg(ArgVR[i]);
+ CallMI->addRegOperand(FPR[FPR_idx], MachineOperand::Use);
++FPR_idx;
break;
}
}
-
- // Emit the correct call instruction based on the type of symbol called.
- if (GlobalAddressSDNode *GASD =
- dyn_cast<GlobalAddressSDNode>(N.getOperand(1))) {
- BuildMI(BB, PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(), true);
- } else if (ExternalSymbolSDNode *ESSDN =
- dyn_cast<ExternalSymbolSDNode>(N.getOperand(1))) {
- BuildMI(BB, PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(), true);
- } else {
- Tmp1 = SelectExpr(N.getOperand(1));
- BuildMI(BB, PPC::OR, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1);
- BuildMI(BB, PPC::MTCTR, 1).addReg(PPC::R12);
- BuildMI(BB, PPC::CALLindirect, 3).addImm(20).addImm(0).addReg(PPC::R12);
- }
+
+ // Put the call instruction in the correct place in the MachineBasicBlock
+ BB->push_back(CallMI);
switch (Node->getValueType(0)) {
default: assert(0 && "Unknown value type for call result!");
OpenPOWER on IntegriCloud