llvm.org GIT mirror llvm / fb11288
Model inline asm constraint which ties an input to an output register as machine operand TIED_TO constraint. This eliminated the need to pre-allocate registers for these. This also allows register allocator can eliminate the unneeded copies. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67512 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 11 years ago
10 changed file(s) with 147 addition(s) and 56 deletion(s). Raw diff Collapse all Expand all
134134 return (Flag & 0xffff) >> 3;
135135 }
136136
137 /// isOutputOperandTiedToUse - Return true if the flag of the inline asm
138 /// operand indicates it is an output that's matched to an input operand.
139 static bool isOutputOperandTiedToUse(unsigned Flag, unsigned &UseIdx) {
140 if (Flag & 0x80000000) {
141 UseIdx = Flag >> 16;
142 return true;
143 }
144 return false;
137 /// isUseOperandTiedToDef - Return true if the flag of the inline asm
138 /// operand indicates it is an use operand that's matched to a def operand.
139 static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx) {
140 if ((Flag & 0x80000000) == 0)
141 return false;
142 Idx = (Flag & ~0x80000000) >> 16;
143 return true;
145144 }
146145
147146
476476 assert(interval.containsOneValue());
477477 unsigned DefIndex = getDefIndex(interval.getValNumInfo(0)->def);
478478 unsigned RedefIndex = getDefIndex(MIIdx);
479 // It cannot be an early clobber MO.
480 assert(!MO.isEarlyClobber() && "Unexpected early clobber!");
479 if (MO.isEarlyClobber())
480 RedefIndex = getUseIndex(MIIdx);
481481
482482 const LiveRange *OldLR = interval.getLiveRangeContaining(RedefIndex-1);
483483 VNInfo *OldValNo = OldLR->valno;
498498 // Value#0 is now defined by the 2-addr instruction.
499499 OldValNo->def = RedefIndex;
500500 OldValNo->copy = 0;
501 if (MO.isEarlyClobber())
502 OldValNo->redefByEC = true;
501503
502504 // Add the new live interval which replaces the range for the input copy.
503505 LiveRange LR(DefIndex, RedefIndex, ValNo);
545547 // live until the end of the block. We've already taken care of the
546548 // rest of the live range.
547549 unsigned defIndex = getDefIndex(MIIdx);
548 // It cannot be an early clobber MO.
549 assert(!MO.isEarlyClobber() && "Unexpected early clobber!");
550 if (MO.isEarlyClobber())
551 defIndex = getUseIndex(MIIdx);
550552
551553 VNInfo *ValNo;
552554 MachineInstr *CopyMI = NULL;
1010 //
1111 //===----------------------------------------------------------------------===//
1212
13 #include "llvm/CodeGen/MachineInstr.h"
1314 #include "llvm/Constants.h"
14 #include "llvm/CodeGen/MachineInstr.h"
15 #include "llvm/InlineAsm.h"
1516 #include "llvm/Value.h"
1617 #include "llvm/CodeGen/MachineFunction.h"
1718 #include "llvm/CodeGen/MachineRegisterInfo.h"
691692 /// isRegReDefinedByTwoAddr - Given the index of a register operand,
692693 /// check if the register def is a re-definition due to two addr elimination.
693694 bool MachineInstr::isRegReDefinedByTwoAddr(unsigned DefIdx) const{
695 if (getOpcode() == TargetInstrInfo::INLINEASM) {
696 assert(DefIdx >= 2);
697 const MachineOperand &MO = getOperand(DefIdx);
698 if (!MO.isReg() || !MO.isDef())
699 return false;
700 // Determine the actual operand no corresponding to this index.
701 unsigned DefNo = 0;
702 for (unsigned i = 1, e = getNumOperands(); i < e; ) {
703 const MachineOperand &FMO = getOperand(i);
704 assert(FMO.isImm());
705 // Skip over this def.
706 i += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1;
707 if (i > DefIdx)
708 break;
709 ++DefNo;
710 }
711 for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
712 const MachineOperand &FMO = getOperand(i);
713 if (!FMO.isImm())
714 continue;
715 if (i+1 >= e || !getOperand(i+1).isReg() || !getOperand(i+1).isUse())
716 continue;
717 unsigned Idx;
718 if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) &&
719 Idx == DefNo)
720 return true;
721 }
722 }
723
694724 assert(getOperand(DefIdx).isDef() && "DefIdx is not a def!");
695725 const TargetInstrDesc &TID = getDesc();
696726 for (unsigned i = 0, e = TID.getNumOperands(); i != e; ++i) {
706736 /// is a register use and it is tied to an def operand. It also returns the def
707737 /// operand index by reference.
708738 bool MachineInstr::isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx){
739 if (getOpcode() == TargetInstrInfo::INLINEASM) {
740 const MachineOperand &MO = getOperand(UseOpIdx);
741 if (!MO.isReg() || !MO.isUse())
742 return false;
743 assert(UseOpIdx > 0);
744 const MachineOperand &UFMO = getOperand(UseOpIdx-1);
745 if (!UFMO.isImm())
746 return false; // Must be physreg uses.
747 unsigned DefNo;
748 if (InlineAsm::isUseOperandTiedToDef(UFMO.getImm(), DefNo)) {
749 if (!DefOpIdx)
750 return true;
751
752 unsigned DefIdx = 1;
753 // Remember to adjust the index. First operand is asm string, then there
754 // is a flag for each.
755 while (DefNo) {
756 const MachineOperand &FMO = getOperand(DefIdx);
757 assert(FMO.isImm());
758 // Skip over this def.
759 DefIdx += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1;
760 --DefNo;
761 }
762 *DefOpIdx = DefIdx+1;
763 return true;
764 }
765 return false;
766 }
767
709768 const TargetInstrDesc &TID = getDesc();
710769 if (UseOpIdx >= TID.getNumOperands())
711770 return false;
49314931 std::vector RegClassRegs;
49324932 const TargetRegisterClass *RC = PhysReg.second;
49334933 if (RC) {
4934 // If this is a tied register, our regalloc doesn't know how to maintain
4935 // the constraint, so we have to pick a register to pin the input/output to.
4936 // If it isn't a matched constraint, go ahead and create vreg and let the
4937 // regalloc do its thing.
4938 if (!OpInfo.hasMatchingInput()) {
4939 RegVT = *PhysReg.second->vt_begin();
4940 if (OpInfo.ConstraintVT == MVT::Other)
4941 ValueVT = RegVT;
4942
4943 // Create the appropriate number of virtual registers.
4944 MachineRegisterInfo &RegInfo = MF.getRegInfo();
4945 for (; NumRegs; --NumRegs)
4946 Regs.push_back(RegInfo.createVirtualRegister(PhysReg.second));
4947
4948 OpInfo.AssignedRegs = RegsForValue(TLI, Regs, RegVT, ValueVT);
4949 return;
4950 }
4951
4952 // Otherwise, we can't allocate it. Let the code below figure out how to
4953 // maintain these constraints.
4954 RegClassRegs.assign(PhysReg.second->begin(), PhysReg.second->end());
4955
4934 RegVT = *PhysReg.second->vt_begin();
4935 if (OpInfo.ConstraintVT == MVT::Other)
4936 ValueVT = RegVT;
4937
4938 // Create the appropriate number of virtual registers.
4939 MachineRegisterInfo &RegInfo = MF.getRegInfo();
4940 for (; NumRegs; --NumRegs)
4941 Regs.push_back(RegInfo.createVirtualRegister(PhysReg.second));
4942
4943 OpInfo.AssignedRegs = RegsForValue(TLI, Regs, RegVT, ValueVT);
4944 return;
49564945 } else {
49574946 // This is a reference to a register class that doesn't directly correspond
49584947 // to an LLVM register class. Allocate NumRegs consecutive, available,
52365225 OpInfo.AssignedRegs.AddInlineAsmOperands(OpInfo.isEarlyClobber ?
52375226 6 /* EARLYCLOBBER REGDEF */ :
52385227 2 /* REGDEF */ ,
5239 OpInfo.hasMatchingInput(),
5240 OpInfo.MatchingInput,
5228 false,
5229 0,
52415230 DAG, AsmNodeOperands);
52425231 break;
52435232 }
52715260 RegsForValue MatchedRegs;
52725261 MatchedRegs.TLI = &TLI;
52735262 MatchedRegs.ValueVTs.push_back(InOperandVal.getValueType());
5274 MatchedRegs.RegVTs.push_back(AsmNodeOperands[CurOp+1].getValueType());
5263 MVT RegVT = AsmNodeOperands[CurOp+1].getValueType();
5264 MatchedRegs.RegVTs.push_back(RegVT);
5265 MachineRegisterInfo &RegInfo = DAG.getMachineFunction().getRegInfo();
52755266 for (unsigned i = 0, e = InlineAsm::getNumOperandRegisters(OpFlag);
5276 i != e; ++i) {
5277 unsigned Reg =
5278 cast(AsmNodeOperands[++CurOp])->getReg();
5279 MatchedRegs.Regs.push_back(Reg);
5280 }
5267 i != e; ++i)
5268 MatchedRegs.Regs.
5269 push_back(RegInfo.createVirtualRegister(TLI.getRegClassFor(RegVT)));
52815270
52825271 // Use the produced MatchedRegs object to
52835272 MatchedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
52845273 Chain, &Flag);
5285 MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, false, 0,
5274 MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/,
5275 true, OpInfo.getMatchedOperand(),
52865276 DAG, AsmNodeOperands);
52875277 break;
52885278 } else {
52905280 assert((InlineAsm::getNumOperandRegisters(OpFlag)) == 1 &&
52915281 "Unexpected number of operands");
52925282 // Add information to the INLINEASM node to know about this input.
5283 // See InlineAsm.h isUseOperandTiedToDef.
5284 OpFlag |= 0x80000000 | (OpInfo.getMatchedOperand() << 16);
52935285 AsmNodeOperands.push_back(DAG.getTargetConstant(OpFlag,
52945286 TLI.getPointerTy()));
52955287 AsmNodeOperands.push_back(AsmNodeOperands[CurOp+1]);
633633
634634 ProcessCopy(&*mi, &*mbbi, Processed);
635635
636 for (unsigned si = 1, e = TID.getNumOperands(); si < e; ++si) {
636 unsigned NumOps = (mi->getOpcode() == TargetInstrInfo::INLINEASM)
637 ? mi->getNumOperands() : TID.getNumOperands();
638 for (unsigned si = 0; si < NumOps; ++si) {
637639 unsigned ti = 0;
638640 if (!mi->isRegTiedToDefOperand(si, &ti))
639641 continue;
659661 unsigned regA = mi->getOperand(ti).getReg();
660662 unsigned regB = mi->getOperand(si).getReg();
661663
662 assert(TargetRegisterInfo::isVirtualRegister(regA) &&
663 TargetRegisterInfo::isVirtualRegister(regB) &&
664 assert(TargetRegisterInfo::isVirtualRegister(regB) &&
664665 "cannot update physical register live information");
665666
666667 #ifndef NDEBUG
752753 }
753754
754755 InstructionRearranged:
755 const TargetRegisterClass* rc = MRI->getRegClass(regA);
756 const TargetRegisterClass* rc = MRI->getRegClass(regB);
756757 MachineInstr *DefMI = MRI->getVRegDef(regB);
757758 // If it's safe and profitable, remat the definition instead of
758759 // copying it.
10161016 case X86::MOV_Fp8032:
10171017 case X86::MOV_Fp8064:
10181018 case X86::MOV_Fp8080: {
1019 unsigned SrcReg = getFPReg(MI->getOperand(1));
1020 unsigned DestReg = getFPReg(MI->getOperand(0));
1021
1019 const MachineOperand &MO1 = MI->getOperand(1);
1020 unsigned SrcReg = getFPReg(MO1);
1021
1022 const MachineOperand &MO0 = MI->getOperand(0);
1023 // These can be created due to inline asm. Two address pass can introduce
1024 // copies from RFP registers to virtual registers.
1025 if (MO0.getReg() == X86::ST0 && SrcReg == 0) {
1026 assert(MO1.isKill());
1027 // Treat %ST0 = MOV_Fp8080 %FP0
1028 // like FpSET_ST0_80 %FP0, %ST0
1029 assert((StackTop == 1 || StackTop == 2)
1030 && "Stack should have one or two element on it to return!");
1031 --StackTop; // "Forget" we have something on the top of stack!
1032 break;
1033 } else if (MO0.getReg() == X86::ST1 && SrcReg == 1) {
1034 assert(MO1.isKill());
1035 // Treat %ST1 = MOV_Fp8080 %FP1
1036 // like FpSET_ST1_80 %FP0, %ST1
1037 // StackTop can be 1 if a FpSET_ST0_* was before this. Exchange them.
1038 if (StackTop == 1) {
1039 BuildMI(*MBB, I, dl, TII->get(X86::XCH_F)).addReg(X86::ST1);
1040 NumFXCH++;
1041 StackTop = 0;
1042 break;
1043 }
1044 assert(StackTop == 2 && "Stack should have two element on it to return!");
1045 --StackTop; // "Forget" we have something on the top of stack!
1046 break;
1047 }
1048
1049 unsigned DestReg = getFPReg(MO0);
10221050 if (MI->killsRegister(X86::FP0+SrcReg)) {
10231051 // If the input operand is killed, we can just change the owner of the
10241052 // incoming stack slot into the result.
None ; RUN: llvm-as < %s | llc | grep {a: %ecx %ecx}
1 ; RUN: llvm-as < %s | llc | grep {b: %ecx %edx %ecx}
0 ; RUN: llvm-as < %s | llc | grep {a:} | not grep ax
1 ; RUN: llvm-as < %s | llc | grep {b:} | not grep ax
22 ; PR2078
33 ; The clobber list says that "ax" is clobbered. Make sure that eax isn't
44 ; allocated to the input/output register.
None ; RUN: llvm-as < %s | llc -march=x86 | grep "#%ebp %eax %edx 8(%esi) %ebx (%edi)"
1 ; RUN: llvm-as < %s | llc -march=x86 -regalloc=local | grep "#%ecx %eax %edx 8(%edi) %ebx (%esi)"
0 ; RUN: llvm-as < %s | llc -march=x86 | grep "#%ebp %edi %esi 8(%edx) %eax (%ebx)"
1 ; RUN: llvm-as < %s | llc -march=x86 -regalloc=local | grep "#%edi %edx %ebp 8(%ebx) %eax (%esi)"
22 ; The 1st, 2nd, 3rd and 5th registers above must all be different. The registers
33 ; referenced in the 4th and 6th operands must not be the same as the 1st or 5th
44 ; operand. There are many combinations that work; this is what llc puts out now.
None ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin | %prcontext End 1 | grep {movl.*%ecx}
0 ; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin | %prcontext End 2 | grep mov
11 ; PR3149
2 ; Make sure the copy after inline asm is not coalesced away.
23
34 @"\01LC" = internal constant [7 x i8] c"n0=%d\0A\00" ; <[7 x i8]*> [#uses=1]
45 @llvm.used = appending global [1 x i8*] [ i8* bitcast (i32 (i64, i64)* @umoddi3 to i8*) ], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0]
0 ; RUN: llvm-as < %s | llc -march=x86-64 | grep movq | count 1
1
2 define i64 @t(i64 %a, i64 %b) nounwind ssp {
3 entry:
4 %asmtmp = tail call i64 asm "rorq $1,$0", "=r,J,0,~{dirflag},~{fpsr},~{flags},~{cc}"(i32 1, i64 %a) nounwind ; [#uses=1]
5 %asmtmp1 = tail call i64 asm "rorq $1,$0", "=r,J,0,~{dirflag},~{fpsr},~{flags},~{cc}"(i32 1, i64 %b) nounwind ; [#uses=1]
6 %0 = add i64 %asmtmp1, %asmtmp ; [#uses=1]
7 ret i64 %0
8 }