llvm.org GIT mirror llvm / f95215f
Use NEON reg-reg moves, where profitable. This reduces "domain-cross" stalls, when we used to mix vfp and neon code (the former were used for reg-reg moves) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85764 91177308-0d34-0410-b5e6-96231b3b80d8 Anton Korobeynikov 10 years ago
8 changed file(s) with 97 addition(s) and 31 deletion(s). Raw diff Collapse all Expand all
124124 "SizeFlag",
125125 "IndexModeBits",
126126 "Form",
127 "isUnaryDataProc"];
127 "isUnaryDataProc",
128 "canXformTo16Bit",
129 "Dom"];
128130 let TSFlagsShifts = [0,
129131 4,
130132 7,
131133 9,
132 15];
134 15,
135 16,
136 17];
133137 }
134138
135139 //===----------------------------------------------------------------------===//
1515 #include "ARMAddressingModes.h"
1616 #include "ARMGenInstrInfo.inc"
1717 #include "ARMMachineFunctionInfo.h"
18 #include "ARMRegisterInfo.h"
1819 #include "llvm/ADT/STLExtras.h"
1920 #include "llvm/CodeGen/LiveVariables.h"
2021 #include "llvm/CodeGen/MachineFrameInfo.h"
2122 #include "llvm/CodeGen/MachineInstrBuilder.h"
2223 #include "llvm/CodeGen/MachineJumpTableInfo.h"
2324 #include "llvm/CodeGen/MachineMemOperand.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
2426 #include "llvm/CodeGen/PseudoSourceValue.h"
2527 #include "llvm/MC/MCAsmInfo.h"
2628 #include "llvm/Support/CommandLine.h"
29 #include "llvm/Support/Debug.h"
2730 #include "llvm/Support/ErrorHandling.h"
2831 using namespace llvm;
2932
3134 EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden,
3235 cl::desc("Enable ARM 2-addr to 3-addr conv"));
3336
34 ARMBaseInstrInfo::ARMBaseInstrInfo()
35 : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)) {
37 ARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget& STI)
38 : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)),
39 Subtarget(STI) {
3640 }
3741
3842 MachineInstr *
503507 case ARM::FCPYS:
504508 case ARM::FCPYD:
505509 case ARM::VMOVD:
506 case ARM::VMOVQ: {
510 case ARM::VMOVQ: {
507511 SrcReg = MI.getOperand(1).getReg();
508512 DstReg = MI.getOperand(0).getReg();
509513 return true;
646650 } else if (DestRC == ARM::SPRRegisterClass) {
647651 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg)
648652 .addReg(SrcReg));
649 } else if ((DestRC == ARM::DPRRegisterClass) ||
650 (DestRC == ARM::DPR_VFP2RegisterClass) ||
651 (DestRC == ARM::DPR_8RegisterClass)) {
652 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg)
653 .addReg(SrcReg));
653 } else if (DestRC == ARM::DPR_VFP2RegisterClass ||
654 DestRC == ARM::DPR_8RegisterClass ||
655 SrcRC == ARM::DPR_VFP2RegisterClass ||
656 SrcRC == ARM::DPR_8RegisterClass) {
657 // Always use neon reg-reg move if source or dest is NEON-only regclass.
658 BuildMI(MBB, I, DL, get(ARM::VMOVD), DestReg).addReg(SrcReg);
659 } else if (DestRC == ARM::DPRRegisterClass) {
660 const ARMBaseRegisterInfo* TRI = &getRegisterInfo();
661
662 // Find the Machine Instruction which defines SrcReg.
663 MachineBasicBlock::iterator J = (I == MBB.begin() ? I : prior(I));
664 while (J != MBB.begin()) {
665 if (J->modifiesRegister(SrcReg, TRI))
666 break;
667 --J;
668 }
669
670 unsigned Domain;
671 if (J->modifiesRegister(SrcReg, TRI)) {
672 Domain = J->getDesc().TSFlags & ARMII::DomainMask;
673 // Instructions in general domain are subreg accesses.
674 // Map them to NEON reg-reg moves.
675 if (Domain == ARMII::DomainGeneral)
676 Domain = ARMII::DomainNEON;
677 } else {
678 // We reached the beginning of the BB and found no instruction defining
679 // the reg. This means that register should be live-in for this BB.
680 // It's always to better to use NEON reg-reg moves.
681 Domain = ARMII::DomainNEON;
682 }
683
684 if ((Domain & ARMII::DomainNEON) && getSubtarget().hasNEON()) {
685 BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg);
686 } else {
687 assert((Domain & ARMII::DomainVFP ||
688 !getSubtarget().hasNEON()) && "Invalid domain!");
689 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg)
690 .addReg(SrcReg));
691 }
654692 } else if (DestRC == ARM::QPRRegisterClass ||
655693 DestRC == ARM::QPR_VFP2RegisterClass) {
656694 BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg);
128128 // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
129129 // a 16-bit Thumb instruction if certain conditions are met.
130130 Xform16Bit = 1 << 16,
131
132 //===------------------------------------------------------------------===//
133 // Code domain.
134 DomainShift = 17,
135 DomainMask = 3 << DomainShift,
136 DomainGeneral = 0 << DomainShift,
137 DomainVFP = 1 << DomainShift,
138 DomainNEON = 2 << DomainShift,
131139
132140 //===------------------------------------------------------------------===//
133141 // Field shifts - such shifts are used to set field while generating
156164 }
157165
158166 class ARMBaseInstrInfo : public TargetInstrInfoImpl {
167 const ARMSubtarget& Subtarget;
159168 protected:
160169 // Can be only subclassed.
161 explicit ARMBaseInstrInfo();
170 explicit ARMBaseInstrInfo(const ARMSubtarget &STI);
162171 public:
163172 // Return the non-pre/post incrementing version of 'Opc'. Return 0
164173 // if there is not such an opcode.
172181 LiveVariables *LV) const;
173182
174183 virtual const ARMBaseRegisterInfo &getRegisterInfo() const =0;
184 const ARMSubtarget &getSubtarget() const { return Subtarget; }
175185
176186 // Branch analysis.
177187 virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
107107 def IndexModePre : IndexMode<1>;
108108 def IndexModePost : IndexMode<2>;
109109
110 // Instruction execution domain.
111 class Domain val> {
112 bits<2> Value = val;
113 }
114 def GenericDomain : Domain<0>;
115 def VFPDomain : Domain<1>; // Instructions in VFP domain only
116 def NeonDomain : Domain<2>; // Instructions in Neon domain only
117 def VFPNeonDomain : Domain<3>; // Instructions in both VFP & Neon domains
118
110119 //===----------------------------------------------------------------------===//
111120
112121 // ARM special operands.
135144 //
136145
137146 class InstARM
138 Format f, string cstr, InstrItinClass itin>
147 Format f, Domain d, string cstr, InstrItinClass itin>
139148 : Instruction {
140149 field bits<32> Inst;
141150
153162
154163 Format F = f;
155164 bits<5> Form = F.Value;
165
166 Domain D = d;
167 bits<2> Dom = D.Value;
156168
157169 //
158170 // Attributes specific to ARM instructions...
166178
167179 class PseudoInst
168180 string asm, list pattern>
169 : InstARM"", itin> {
181 : InstARMGenericDomain,
182 "", itin> {
170183 let OutOperandList = oops;
171184 let InOperandList = iops;
172185 let AsmString = asm;
178191 IndexMode im, Format f, InstrItinClass itin,
179192 string opc, string asm, string cstr,
180193 list pattern>
181 : InstARMcstr, itin> {
194 : InstARMGenericDomain, cstr, itin> {
182195 let OutOperandList = oops;
183196 let InOperandList = !con(iops, (ops pred:$p));
184197 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
193206 IndexMode im, Format f, InstrItinClass itin,
194207 string opc, string asm, string cstr,
195208 list pattern>
196 : InstARMcstr, itin> {
209 : InstARMGenericDomain, cstr, itin> {
197210 let OutOperandList = oops;
198211 let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
199212 let AsmString = !strconcat(opc, !strconcat("${p}${s}", asm));
205218 class XI
206219 IndexMode im, Format f, InstrItinClass itin,
207220 string asm, string cstr, list pattern>
208 : InstARMcstr, itin> {
221 : InstARMGenericDomain, cstr, itin> {
209222 let OutOperandList = oops;
210223 let InOperandList = iops;
211224 let AsmString = asm;
806819
807820 class ThumbI
808821 InstrItinClass itin, string asm, string cstr, list pattern>
809 : InstARMcstr, itin> {
822 : InstARMGenericDomain, cstr, itin> {
810823 let OutOperandList = oops;
811824 let InOperandList = iops;
812825 let AsmString = asm;
832845 // Thumb1 only
833846 class Thumb1I
834847 InstrItinClass itin, string asm, string cstr, list pattern>
835 : InstARMcstr, itin> {
848 : InstARMGenericDomain, cstr, itin> {
836849 let OutOperandList = oops;
837850 let InOperandList = iops;
838851 let AsmString = asm;
860873 class Thumb1sI
861874 InstrItinClass itin,
862875 string opc, string asm, string cstr, list pattern>
863 : InstARMcstr, itin> {
876 : InstARMGenericDomain, cstr, itin> {
864877 let OutOperandList = !con(oops, (ops s_cc_out:$s));
865878 let InOperandList = !con(iops, (ops pred:$p));
866879 let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
882895 class Thumb1pI
883896 InstrItinClass itin,
884897 string opc, string asm, string cstr, list pattern>
885 : InstARMcstr, itin> {
898 : InstARMGenericDomain, cstr, itin> {
886899 let OutOperandList = oops;
887900 let InOperandList = !con(iops, (ops pred:$p));
888901 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
917930 class Thumb2I
918931 InstrItinClass itin,
919932 string opc, string asm, string cstr, list pattern>
920 : InstARMcstr, itin> {
933 : InstARMGenericDomain, cstr, itin> {
921934 let OutOperandList = oops;
922935 let InOperandList = !con(iops, (ops pred:$p));
923936 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
933946 class Thumb2sI
934947 InstrItinClass itin,
935948 string opc, string asm, string cstr, list pattern>
936 : InstARMcstr, itin> {
949 : InstARMGenericDomain, cstr, itin> {
937950 let OutOperandList = oops;
938951 let InOperandList = !con(iops, (ops pred:$p, cc_out:$s));
939952 let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm));
945958 class Thumb2XI
946959 InstrItinClass itin,
947960 string asm, string cstr, list pattern>
948 : InstARMcstr, itin> {
961 : InstARMGenericDomain, cstr, itin> {
949962 let OutOperandList = oops;
950963 let InOperandList = iops;
951964 let AsmString = asm;
9921005 class T2Iidxldst
9931006 InstrItinClass itin,
9941007 string opc, string asm, string cstr, list pattern>
995 : InstARMcstr, itin> {
1008 : InstARMGenericDomain, cstr, itin> {
9961009 let OutOperandList = oops;
9971010 let InOperandList = !con(iops, (ops pred:$p));
9981011 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
10251038 class VFPI
10261039 IndexMode im, Format f, InstrItinClass itin,
10271040 string opc, string asm, string cstr, list pattern>
1028 : InstARMcstr, itin> {
1041 : InstARMVFPDomain, cstr, itin> {
10291042 let OutOperandList = oops;
10301043 let InOperandList = !con(iops, (ops pred:$p));
10311044 let AsmString = !strconcat(opc, !strconcat("${p}", asm));
10371050 class VFPXI
10381051 IndexMode im, Format f, InstrItinClass itin,
10391052 string asm, string cstr, list pattern>
1040 : InstARMcstr, itin> {
1053 : InstARMVFPDomain, cstr, itin> {
10411054 let OutOperandList = oops;
10421055 let InOperandList = iops;
10431056 let AsmString = asm;
11981211
11991212 class NeonI
12001213 string asm, string cstr, list pattern>
1201 : InstARMcstr, itin> {
1214 : InstARMNeonDomain, cstr, itin> {
12021215 let OutOperandList = oops;
12031216 let InOperandList = iops;
12041217 let AsmString = asm;
2424 using namespace llvm;
2525
2626 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
27 : RI(*this, STI), Subtarget(STI) {
27 : ARMBaseInstrInfo(STI), RI(*this, STI) {
2828 }
2929
3030 unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const {
2424
2525 class ARMInstrInfo : public ARMBaseInstrInfo {
2626 ARMRegisterInfo RI;
27 const ARMSubtarget &Subtarget;
2827 public:
2928 explicit ARMInstrInfo(const ARMSubtarget &STI);
3029
2323
2424 using namespace llvm;
2525
26 Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI) : RI(*this, STI) {
26 Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI)
27 : ARMBaseInstrInfo(STI), RI(*this, STI) {
2728 }
2829
2930 unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const {
2424
2525 using namespace llvm;
2626
27 Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI) : RI(*this, STI) {
27 Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
28 : ARMBaseInstrInfo(STI), RI(*this, STI) {
2829 }
2930
3031 unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const {