llvm.org GIT mirror llvm / 6470a11
Next round of tail call changes. Register used in a tail call must not be callee-saved; following x86, add a new regclass to represent this. Also fixes a couple of bugs. Still disabled by default; Thumb doesn't work yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106053 91177308-0d34-0410-b5e6-96231b3b80d8 Dale Johannesen 10 years ago
8 changed file(s) with 110 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
595595 return true;
596596 }
597597 case ARM::MOVr:
598 case ARM::MOVr_TC:
598599 case ARM::tMOVr:
599600 case ARM::tMOVgpr2tgpr:
600601 case ARM::tMOVtgpr2gpr:
700701 const TargetRegisterClass *DestRC,
701702 const TargetRegisterClass *SrcRC,
702703 DebugLoc DL) const {
703 // tGPR is used sometimes in ARM instructions that need to avoid using
704 // certain registers. Just treat it as GPR here.
705 if (DestRC == ARM::tGPRRegisterClass)
704 // tGPR or tcGPR is used sometimes in ARM instructions that need to avoid
705 // using certain registers. Just treat them as GPR here.
706 if (DestRC == ARM::tGPRRegisterClass || DestRC == ARM::tcGPRRegisterClass)
706707 DestRC = ARM::GPRRegisterClass;
707 if (SrcRC == ARM::tGPRRegisterClass)
708 if (SrcRC == ARM::tGPRRegisterClass || SrcRC == ARM::tcGPRRegisterClass)
708709 SrcRC = ARM::GPRRegisterClass;
709710
710711 // Allow DPR / DPR_VFP2 / DPR_8 cross-class copies.
798799
799800 // tGPR is used sometimes in ARM instructions that need to avoid using
800801 // certain registers. Just treat it as GPR here.
801 if (RC == ARM::tGPRRegisterClass)
802 if (RC == ARM::tGPRRegisterClass || RC == ARM::tcGPRRegisterClass)
802803 RC = ARM::GPRRegisterClass;
803804
804805 if (RC == ARM::GPRRegisterClass) {
889890
890891 // tGPR is used sometimes in ARM instructions that need to avoid using
891892 // certain registers. Just treat it as GPR here.
892 if (RC == ARM::tGPRRegisterClass)
893 if (RC == ARM::tGPRRegisterClass || RC == ARM::tcGPRRegisterClass)
893894 RC = ARM::GPRRegisterClass;
894895
895896 if (RC == ARM::GPRRegisterClass) {
16611661 addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
16621662 JumpTarget.getTargetFlags());
16631663 } else if (RetOpcode == ARM::TCRETURNri) {
1664 BuildMI(MBB, MBBI, dl, TII.get(ARM::TAILJMPr), JumpTarget.getReg());
1664 BuildMI(MBB, MBBI, dl, TII.get(ARM::TAILJMPr)).
1665 addReg(JumpTarget.getReg(), RegState::Kill);
16651666 } else if (RetOpcode == ARM::TCRETURNriND) {
1666 BuildMI(MBB, MBBI, dl, TII.get(ARM::TAILJMPrND), JumpTarget.getReg());
1667 BuildMI(MBB, MBBI, dl, TII.get(ARM::TAILJMPrND)).
1668 addReg(JumpTarget.getReg(), RegState::Kill);
16671669 }
16681670
16691671 MachineInstr *NewMI = prior(MBBI);
1670 for (unsigned i = 2, e = MBBI->getNumOperands(); i != e; ++i)
1672 for (unsigned i = 1, e = MBBI->getNumOperands(); i != e; ++i)
16711673 NewMI->addOperand(MBBI->getOperand(i));
16721674
16731675 // Delete the pseudo instruction TCRETURN.
11081108 // Build a sequence of copy-to-reg nodes chained together with token chain
11091109 // and flag operands which copy the outgoing args into the appropriate regs.
11101110 SDValue InFlag;
1111 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1112 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
1113 RegsToPass[i].second, InFlag);
1114 InFlag = Chain.getValue(1);
1115 }
1111 // Tail call byval lowering might overwrite argument registers so in case of
1112 // tail call optimization the copies to registers are lowered later.
1113 if (!isTailCall)
1114 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
1115 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
1116 RegsToPass[i].second, InFlag);
1117 InFlag = Chain.getValue(1);
1118 }
11161119
11171120 // For tail calls lower the arguments to the 'real' stack slot.
11181121 if (isTailCall) {
348348 }];
349349 }
350350
351 // For tail calls, we can't use callee-saved registers, as they are restored
352 // to the saved value before the tail call, which would clobber a call address.
353 // Note, getMinimalPhysRegClass(R0) returns tGPR because of the names of
354 // this class and the preceding one(!) This is what we want.
355 def tcGPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R9, R12]> {
356 let MethodProtos = [{
357 iterator allocation_order_begin(const MachineFunction &MF) const;
358 iterator allocation_order_end(const MachineFunction &MF) const;
359 }];
360 let MethodBodies = [{
361 // R9 is available.
362 static const unsigned ARM_GPR_R9_TC[] = {
363 ARM::R0, ARM::R1, ARM::R2, ARM::R3,
364 ARM::R9, ARM::R12 };
365 // R9 is not available.
366 static const unsigned ARM_GPR_NOR9_TC[] = {
367 ARM::R0, ARM::R1, ARM::R2, ARM::R3,
368 ARM::R12 };
369
370 // For Thumb1 mode, we don't want to allocate hi regs at all, as we
371 // don't know how to spill them. If we make our prologue/epilogue code
372 // smarter at some point, we can go back to using the above allocation
373 // orders for the Thumb1 instructions that know how to use hi regs.
374 static const unsigned THUMB_GPR_AO_TC[] = {
375 ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
376
377 tcGPRClass::iterator
378 tcGPRClass::allocation_order_begin(const MachineFunction &MF) const {
379 const TargetMachine &TM = MF.getTarget();
380 const ARMSubtarget &Subtarget = TM.getSubtarget();
381 if (Subtarget.isThumb1Only())
382 return THUMB_GPR_AO_TC;
383 if (Subtarget.isTargetDarwin()) {
384 if (Subtarget.isR9Reserved())
385 return ARM_GPR_NOR9_TC;
386 else
387 return ARM_GPR_R9_TC;
388 } else {
389 if (Subtarget.isR9Reserved())
390 return ARM_GPR_NOR9_TC;
391 else if (Subtarget.isThumb())
392 return ARM_GPR_R9_TC;
393 else
394 return ARM_GPR_R9_TC;
395 }
396 }
397
398 tcGPRClass::iterator
399 tcGPRClass::allocation_order_end(const MachineFunction &MF) const {
400 const TargetMachine &TM = MF.getTarget();
401 const ARMSubtarget &Subtarget = TM.getSubtarget();
402 GPRClass::iterator I;
403
404 if (Subtarget.isThumb1Only()) {
405 I = THUMB_GPR_AO_TC + (sizeof(THUMB_GPR_AO_TC)/sizeof(unsigned));
406 return I;
407 }
408
409 if (Subtarget.isTargetDarwin()) {
410 if (Subtarget.isR9Reserved())
411 I = ARM_GPR_NOR9_TC + (sizeof(ARM_GPR_NOR9_TC)/sizeof(unsigned));
412 else
413 I = ARM_GPR_R9_TC + (sizeof(ARM_GPR_R9_TC)/sizeof(unsigned));
414 } else {
415 if (Subtarget.isR9Reserved())
416 I = ARM_GPR_NOR9_TC + (sizeof(ARM_GPR_NOR9_TC)/sizeof(unsigned));
417 else if (Subtarget.isThumb())
418 I = ARM_GPR_R9_TC + (sizeof(ARM_GPR_R9_TC)/sizeof(unsigned));
419 else
420 I = ARM_GPR_R9_TC + (sizeof(ARM_GPR_R9_TC)/sizeof(unsigned));
421 }
422 return I;
423 }
424 }];
425 }
426
427
351428 // Scalar single precision floating point register class..
352429 def SPR : RegisterClass<"ARM", [f32], 32, [S0, S1, S2, S3, S4, S5, S6, S7, S8,
353430 S9, S10, S11, S12, S13, S14, S15, S16, S17, S18, S19, S20, S21, S22,
3838 const TargetRegisterClass *DestRC,
3939 const TargetRegisterClass *SrcRC,
4040 DebugLoc DL) const {
41 if (DestRC == ARM::GPRRegisterClass) {
42 if (SrcRC == ARM::GPRRegisterClass) {
41 if (DestRC == ARM::GPRRegisterClass || DestRC == ARM::tcGPRRegisterClass) {
42 if (SrcRC == ARM::GPRRegisterClass || SrcRC == ARM::tcGPRRegisterClass) {
4343 BuildMI(MBB, I, DL, get(ARM::tMOVgpr2gpr), DestReg).addReg(SrcReg);
4444 return true;
4545 } else if (SrcRC == ARM::tGPRRegisterClass) {
4747 return true;
4848 }
4949 } else if (DestRC == ARM::tGPRRegisterClass) {
50 if (SrcRC == ARM::GPRRegisterClass) {
50 if (SrcRC == ARM::GPRRegisterClass || SrcRC == ARM::tcGPRRegisterClass) {
5151 BuildMI(MBB, I, DL, get(ARM::tMOVgpr2tgpr), DestReg).addReg(SrcReg);
5252 return true;
5353 } else if (SrcRC == ARM::tGPRRegisterClass) {
4141 const TargetRegisterClass *DestRC,
4242 const TargetRegisterClass *SrcRC,
4343 DebugLoc DL) const {
44 if (DestRC == ARM::GPRRegisterClass) {
45 if (SrcRC == ARM::GPRRegisterClass) {
44 if (DestRC == ARM::GPRRegisterClass || DestRC == ARM::tcGPRRegisterClass) {
45 if (SrcRC == ARM::GPRRegisterClass || SrcRC == ARM::tcGPRRegisterClass) {
4646 BuildMI(MBB, I, DL, get(ARM::tMOVgpr2gpr), DestReg).addReg(SrcReg);
4747 return true;
4848 } else if (SrcRC == ARM::tGPRRegisterClass) {
5050 return true;
5151 }
5252 } else if (DestRC == ARM::tGPRRegisterClass) {
53 if (SrcRC == ARM::GPRRegisterClass) {
53 if (SrcRC == ARM::GPRRegisterClass || SrcRC == ARM::tcGPRRegisterClass) {
5454 BuildMI(MBB, I, DL, get(ARM::tMOVgpr2tgpr), DestReg).addReg(SrcReg);
5555 return true;
5656 } else if (SrcRC == ARM::tGPRRegisterClass) {
6969 unsigned SrcReg, bool isKill, int FI,
7070 const TargetRegisterClass *RC,
7171 const TargetRegisterInfo *TRI) const {
72 if (RC == ARM::GPRRegisterClass || RC == ARM::tGPRRegisterClass) {
72 if (RC == ARM::GPRRegisterClass || RC == ARM::tGPRRegisterClass ||
73 RC == ARM::tcGPRRegisterClass) {
7374 DebugLoc DL;
7475 if (I != MBB.end()) DL = I->getDebugLoc();
7576
9495 unsigned DestReg, int FI,
9596 const TargetRegisterClass *RC,
9697 const TargetRegisterInfo *TRI) const {
97 if (RC == ARM::GPRRegisterClass || RC == ARM::tGPRRegisterClass) {
98 if (RC == ARM::GPRRegisterClass || RC == ARM::tGPRRegisterClass ||
99 RC == ARM::tcGPRRegisterClass) {
98100 DebugLoc DL;
99101 if (I != MBB.end()) DL = I->getDebugLoc();
100102
15781578 if (Name == "TCRETURNdi" || Name == "TCRETURNdiND" ||
15791579 Name == "TCRETURNri" || Name == "TCRETURNriND" ||
15801580 Name == "TAILJMPd" || Name == "TAILJMPdND" ||
1581 Name == "TAILJMPr" || Name == "TAILJMPrND")
1581 Name == "TAILJMPr" || Name == "TAILJMPrND" ||
1582 Name == "MOVr_TC")
15821583 return false;
15831584
15841585 // VLDMQ/VSTMQ can be hanlded with the more generic VLDMD/VSTMD.
569569 static int ARMFlagFromOpName(LiteralConstantEmitter *type,
570570 const std::string &name) {
571571 REG("GPR");
572 REG("tcGPR");
572573 REG("cc_out");
573574 REG("s_cc_out");
574575 REG("tGPR");