llvm.org GIT mirror llvm / f31ac9d
[globalisel][tablegen] Compute available feature bits correctly. Summary: Predicate<> now has a field to indicate how often it must be recomputed. Currently, there are two frequencies, per-module (RecomputePerFunction==0) and per-function (RecomputePerFunction==1). Per-function predicates are currently recomputed more frequently than necessary since the only predicate in this category is cheap to test. Per-module predicates are now computed in getSubtargetImpl() while per-function predicates are computed in selectImpl(). Tablegen now manages the PredicateBitset internally. It should only be necessary to add the required includes. Also fixed a problem revealed by the test case where constrainSelectedInstRegOperands() would attempt to tie operands that BuildMI had already tied. Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar Reviewed By: rovka Subscribers: kristof.beyls, igorb, llvm-commits Differential Revision: https://reviews.llvm.org/D32491 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301750 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Sanders 3 years ago
19 changed file(s) with 215 addition(s) and 106 deletion(s). Raw diff Collapse all Expand all
6060 public:
6161 virtual ~InstructionSelector() {}
6262
63 /// This is executed before selecting a function.
64 virtual void beginFunction(const MachineFunction &MF) {}
65
6663 /// Select the (possibly generic) instruction \p I to only use target-specific
6764 /// opcodes. It is OK to insert multiple instructions, but they cannot be
6865 /// generic pre-isel instructions.
529529 /// PredicateName - User-level name to use for the predicate. Mainly for use
530530 /// in diagnostics such as missing feature errors in the asm matcher.
531531 string PredicateName = "";
532
533 /// Setting this to '1' indicates that the predicate must be recomputed on
534 /// every function change. Most predicates can leave this at '0'.
535 ///
536 /// Ignored by SelectionDAG, it always recomputes the predicate on every use.
537 bit RecomputePerFunction = 0;
532538 }
533539
534540 /// NoHonorSignDependentRounding - This predicate is true if support for
5757 MO.setReg(constrainOperandRegClass(MF, TRI, MRI, TII, RBI, I, I.getDesc(),
5858 Reg, OpI));
5959
60 // Tie uses to defs as indicated in MCInstrDesc.
60 // Tie uses to defs as indicated in MCInstrDesc if this hasn't already been
61 // done.
6162 if (MO.isUse()) {
6263 int DefIdx = I.getDesc().getOperandConstraint(OpI, MCOI::TIED_TO);
63 if (DefIdx != -1)
64 if (DefIdx != -1 && !I.isRegTiedToUseOperand(DefIdx))
6465 I.tieOperands(DefIdx, OpI);
6566 }
6667 }
313313 // AArch64 Instruction Predicate Definitions.
314314 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
315315 def IsNotDarwin: Predicate<"!Subtarget->isTargetDarwin()">;
316 def ForCodeSize : Predicate<"ForCodeSize">;
317 def NotForCodeSize : Predicate<"!ForCodeSize">;
316 def ForCodeSize : Predicate<"Subtarget->getForCodeSize()">;
317 def NotForCodeSize : Predicate<"!Subtarget->getForCodeSize()">;
318318
319319 include "AArch64InstrFormats.td"
320320
5050 const AArch64Subtarget &STI,
5151 const AArch64RegisterBankInfo &RBI);
5252
53 void beginFunction(const MachineFunction &MF) override;
5453 bool select(MachineInstr &I) const override;
5554
5655 private:
7372 const AArch64InstrInfo &TII;
7473 const AArch64RegisterInfo &TRI;
7574 const AArch64RegisterBankInfo &RBI;
76 bool ForCodeSize;
77
78 PredicateBitset AvailableFeatures;
79 PredicateBitset
80 computeAvailableFeatures(const MachineFunction *MF,
81 const AArch64Subtarget *Subtarget) const;
75
76 #define GET_GLOBALISEL_PREDICATES_DECL
77 #include "AArch64GenGlobalISel.inc"
78 #undef GET_GLOBALISEL_PREDICATES_DECL
8279
8380 // We declare the temporaries used by selectImpl() in the class to minimize the
8481 // cost of constructing placeholder values.
9794 const AArch64TargetMachine &TM, const AArch64Subtarget &STI,
9895 const AArch64RegisterBankInfo &RBI)
9996 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
100 TRI(*STI.getRegisterInfo()), RBI(RBI), ForCodeSize(), AvailableFeatures()
97 TRI(*STI.getRegisterInfo()), RBI(RBI),
98 #define GET_GLOBALISEL_PREDICATES_INIT
99 #include "AArch64GenGlobalISel.inc"
100 #undef GET_GLOBALISEL_PREDICATES_INIT
101101 #define GET_GLOBALISEL_TEMPORARIES_INIT
102102 #include "AArch64GenGlobalISel.inc"
103103 #undef GET_GLOBALISEL_TEMPORARIES_INIT
576576 return true;
577577 }
578578
579 void AArch64InstructionSelector::beginFunction(
580 const MachineFunction &MF) {
581 ForCodeSize = MF.getFunction()->optForSize();
582 AvailableFeatures = computeAvailableFeatures(&MF, &STI);
583 }
584
585579 bool AArch64InstructionSelector::select(MachineInstr &I) const {
586580 assert(I.getParent() && "Instruction should be in a basic block!");
587581 assert(I.getParent()->getParent() && "Instruction should be in a function!");
112112
113113 AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
114114 const std::string &FS,
115 const TargetMachine &TM, bool LittleEndian)
115 const TargetMachine &TM, bool LittleEndian,
116 bool ForCodeSize)
116117 : AArch64GenSubtargetInfo(TT, CPU, FS), ReserveX18(TT.isOSDarwin()),
117118 IsLittle(LittleEndian), TargetTriple(TT), FrameLowering(),
118119 InstrInfo(initializeSubtargetDependencies(FS, CPU)), TSInfo(),
119 TLInfo(TM, *this), GISel() {}
120 TLInfo(TM, *this), GISel(), ForCodeSize(ForCodeSize) {}
120121
121122 const CallLowering *AArch64Subtarget::getCallLowering() const {
122123 assert(GISel && "Access to GlobalISel APIs not set");
123123 /// an optional library.
124124 std::unique_ptr GISel;
125125
126 bool ForCodeSize;
127
126128 private:
127129 /// initializeSubtargetDependencies - Initializes using CPUString and the
128130 /// passed in feature string so that we can use initializer lists for
138140 /// of the specified triple.
139141 AArch64Subtarget(const Triple &TT, const std::string &CPU,
140142 const std::string &FS, const TargetMachine &TM,
141 bool LittleEndian);
143 bool LittleEndian, bool ForCodeSize);
142144
143145 /// This object will take onwership of \p GISelAccessor.
144146 void setGISelAccessor(GISelAccessor &GISel) {
261263 }
262264 }
263265
266 bool getForCodeSize() const { return ForCodeSize; }
267
264268 /// ParseSubtargetFeatures - Parses features string setting specified
265269 /// subtarget options. Definition of function is auto generated by tblgen.
266270 void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
254254 AArch64TargetMachine::getSubtargetImpl(const Function &F) const {
255255 Attribute CPUAttr = F.getFnAttribute("target-cpu");
256256 Attribute FSAttr = F.getFnAttribute("target-features");
257 bool ForCodeSize = F.optForSize();
257258
258259 std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
259260 ? CPUAttr.getValueAsString().str()
261262 std::string FS = !FSAttr.hasAttribute(Attribute::None)
262263 ? FSAttr.getValueAsString().str()
263264 : TargetFS;
264
265 auto &I = SubtargetMap[CPU + FS];
265 std::string ForCodeSizeStr =
266 std::string(ForCodeSize ? "+" : "-") + "forcodesize";
267
268 auto &I = SubtargetMap[CPU + FS + ForCodeSizeStr];
266269 if (!I) {
267270 // This needs to be done before we create a new subtarget since any
268271 // creation will depend on the TM and the code generation flags on the
269272 // function that reside in TargetOptions.
270273 resetTargetOptions(F);
271274 I = llvm::make_unique(TargetTriple, CPU, FS, *this,
272 isLittle);
275 isLittle, ForCodeSize);
273276 #ifndef LLVM_BUILD_GLOBAL_ISEL
274277 GISelAccessor *GISel = new GISelAccessor();
275278 #else
876876 def IsWin64 : Predicate<"Subtarget->isTargetWin64()">;
877877 def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">;
878878 def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||"
879 "Subtarget->getFrameLowering()->hasFP(*MF)">;
879 "Subtarget->getFrameLowering()->hasFP(*MF)"> {
880 let RecomputePerFunction = 1;
881 }
880882 def IsPS4 : Predicate<"Subtarget->isTargetPS4()">;
881883 def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">;
882884 def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
886888 def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
887889 "TM.getCodeModel() == CodeModel::Kernel">;
888890 def IsNotPIC : Predicate<"!TM.isPositionIndependent()">;
889 def OptForSize : Predicate<"OptForSize">;
890 def OptForMinSize : Predicate<"OptForMinSize">;
891 def OptForSpeed : Predicate<"!OptForSize">;
891 def OptForSize : Predicate<"Subtarget->getOptForSize()">;
892 def OptForMinSize : Predicate<"Subtarget->getOptForMinSize()">;
893 def OptForSpeed : Predicate<"!Subtarget->getOptForSize()">;
892894 def FastBTMem : Predicate<"!Subtarget->isBTMemSlow()">;
893895 def CallImmAddr : Predicate<"Subtarget->isLegalToCallImmediateAddr()">;
894896 def FavorMemIndirectCall : Predicate<"!Subtarget->callRegIndirect()">;
4747 X86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &STI,
4848 const X86RegisterBankInfo &RBI);
4949
50 void beginFunction(const MachineFunction &MF) override;
5150 bool select(MachineInstr &I) const override;
5251
5352 private:
7978 const X86InstrInfo &TII;
8079 const X86RegisterInfo &TRI;
8180 const X86RegisterBankInfo &RBI;
82 bool OptForSize;
83 bool OptForMinSize;
84
85 PredicateBitset AvailableFeatures;
86 PredicateBitset computeAvailableFeatures(const MachineFunction *MF,
87 const X86Subtarget *Subtarget) const;
81
82 #define GET_GLOBALISEL_PREDICATES_DECL
83 #include "X86GenGlobalISel.inc"
84 #undef GET_GLOBALISEL_PREDICATES_DECL
8885
8986 #define GET_GLOBALISEL_TEMPORARIES_DECL
9087 #include "X86GenGlobalISel.inc"
10198 const X86Subtarget &STI,
10299 const X86RegisterBankInfo &RBI)
103100 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
104 TRI(*STI.getRegisterInfo()), RBI(RBI), OptForSize(false),
105 OptForMinSize(false), AvailableFeatures()
101 TRI(*STI.getRegisterInfo()), RBI(RBI),
102 #define GET_GLOBALISEL_PREDICATES_INIT
103 #include "X86GenGlobalISel.inc"
104 #undef GET_GLOBALISEL_PREDICATES_INIT
106105 #define GET_GLOBALISEL_TEMPORARIES_INIT
107106 #include "X86GenGlobalISel.inc"
108107 #undef GET_GLOBALISEL_TEMPORARIES_INIT
203202 }
204203 I.setDesc(TII.get(X86::COPY));
205204 return true;
206 }
207
208 void X86InstructionSelector::beginFunction(const MachineFunction &MF) {
209 OptForSize = MF.getFunction()->optForSize();
210 OptForMinSize = MF.getFunction()->optForMinSize();
211 AvailableFeatures = computeAvailableFeatures(&MF, &STI);
212205 }
213206
214207 bool X86InstructionSelector::select(MachineInstr &I) const {
325325
326326 X86Subtarget::X86Subtarget(const Triple &TT, StringRef CPU, StringRef FS,
327327 const X86TargetMachine &TM,
328 unsigned StackAlignOverride)
328 unsigned StackAlignOverride, bool OptForSize,
329 bool OptForMinSize)
329330 : X86GenSubtargetInfo(TT, CPU, FS), X86ProcFamily(Others),
330331 PICStyle(PICStyles::None), TM(TM), TargetTriple(TT),
331332 StackAlignOverride(StackAlignOverride),
334335 TargetTriple.getEnvironment() != Triple::CODE16),
335336 In16BitMode(TargetTriple.getArch() == Triple::x86 &&
336337 TargetTriple.getEnvironment() == Triple::CODE16),
337 InstrInfo(initializeSubtargetDependencies(CPU, FS)),
338 TLInfo(TM, *this), FrameLowering(*this, getStackAlignment()) {
338 InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this),
339 FrameLowering(*this, getStackAlignment()), OptForSize(OptForSize),
340 OptForMinSize(OptForMinSize) {
339341 // Determine the PICStyle based on the target selected.
340342 if (!isPositionIndependent())
341343 setPICStyle(PICStyles::None);
327327 X86TargetLowering TLInfo;
328328 X86FrameLowering FrameLowering;
329329
330 bool OptForSize;
331 bool OptForMinSize;
332
330333 public:
331334 /// This constructor initializes the data members to match that
332335 /// of the specified triple.
333336 ///
334337 X86Subtarget(const Triple &TT, StringRef CPU, StringRef FS,
335 const X86TargetMachine &TM, unsigned StackAlignOverride);
338 const X86TargetMachine &TM, unsigned StackAlignOverride,
339 bool OptForSize, bool OptForMinSize);
336340
337341 /// This object will take onwership of \p GISelAccessor.
338342 void setGISelAccessor(GISelAccessor &GISel) { this->GISel.reset(&GISel); }
498502 bool isSLM() const { return X86ProcFamily == IntelSLM; }
499503 bool useSoftFloat() const { return UseSoftFloat; }
500504
505 bool getOptForSize() const { return OptForSize; }
506 bool getOptForMinSize() const { return OptForMinSize; }
507
501508 /// Use mfence if we have SSE2 or we're on x86-64 (even if we asked for
502509 /// no-sse2). There isn't any reason to disable it if the target processor
503510 /// supports it.
267267
268268 FS = Key.substr(CPU.size());
269269
270 bool OptForSize = F.optForSize();
271 bool OptForMinSize = F.optForMinSize();
272
273 Key += std::string(OptForSize ? "+" : "-") + "optforsize";
274 Key += std::string(OptForMinSize ? "+" : "-") + "optforminsize";
275
270276 auto &I = SubtargetMap[Key];
271277 if (!I) {
272278 // This needs to be done before we create a new subtarget since any
274280 // function that reside in TargetOptions.
275281 resetTargetOptions(F);
276282 I = llvm::make_unique(TargetTriple, CPU, FS, *this,
277 Options.StackAlignmentOverride);
283 Options.StackAlignmentOverride,
284 OptForSize, OptForMinSize);
278285 #ifndef LLVM_BUILD_GLOBAL_ISEL
279286 GISelAccessor *GISel = new GISelAccessor();
280287 #else
285292
286293 auto *RBI = new X86RegisterBankInfo(*I->getRegisterInfo());
287294 GISel->RegBankInfo.reset(RBI);
288 GISel->InstSelector.reset(createX86InstructionSelector(*this, *I, *RBI));
295 GISel->InstSelector.reset(createX86InstructionSelector(
296 *this, *I, *RBI));
289297 #endif
290298 I->setGISelAccessor(*GISel);
291299 }
0 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=ALL,INC
1 # RUN: llc -mtriple=x86_64-linux-gnu -mattr=+slow-incdec -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=ALL,ADD
2
3 --- |
4 define i8 @test_add_i8(i8 %arg1) {
5 %ret = add i8 %arg1, 1
6 ret i8 %ret
7 }
8 ...
9
10 ---
11 name: test_add_i8
12 legalized: true
13 regBankSelected: true
14 # ALL: registers:
15 # ALL-NEXT: - { id: 0, class: gr8 }
16 # INC-NEXT: - { id: 1, class: gpr }
17 # ADD-NEXT: - { id: 1, class: gr8 }
18 # ALL-NEXT: - { id: 2, class: gr8 }
19 registers:
20 - { id: 0, class: gpr }
21 - { id: 1, class: gpr }
22 - { id: 2, class: gpr }
23 # ALL: %0 = COPY %al
24 # INC-NEXT: %2 = INC8r %0
25 # ADD-NEXT: %1 = MOV8ri 1
26 # ADD-NEXT: %2 = ADD8rr %0, %1
27 body: |
28 bb.1 (%ir-block.0):
29 liveins: %al
30
31 %0(s8) = COPY %al
32 %1(s8) = G_CONSTANT i8 1
33 %2(s8) = G_ADD %0, %1
34 %al = COPY %2(s8)
35
36 ...
3131
3232 def HasA : Predicate<"Subtarget->hasA()">;
3333 def HasB : Predicate<"Subtarget->hasB()">;
34 def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; }
3435
3536 //===- Test the function boilerplate. -------------------------------------===//
3637
3738 // CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {
3839 // CHECK-NEXT: Feature_HasABit = 0,
3940 // CHECK-NEXT: Feature_HasBBit = 1,
41 // CHECK-NEXT: Feature_HasCBit = 2,
4042 // CHECK-NEXT: };
4143
4244 // CHECK-LABEL: static const char *SubtargetFeatureNames[] = {
4345 // CHECK-NEXT: "Feature_HasA",
4446 // CHECK-NEXT: "Feature_HasB",
47 // CHECK-NEXT: "Feature_HasC",
4548 // CHECK-NEXT: nullptr
4649 // CHECK-NEXT: };
4750
4851 // CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
49 // CHECK-NEXT: computeAvailableFeatures(const MachineFunction *MF, const MyTargetSubtarget *Subtarget) const {
52 // CHECK-NEXT: computeAvailableModuleFeatures(const MyTargetSubtarget *Subtarget) const {
5053 // CHECK-NEXT: PredicateBitset Features;
5154 // CHECK-NEXT: if (Subtarget->hasA())
5255 // CHECK-NEXT: Features[Feature_HasABit] = 1;
5356 // CHECK-NEXT: if (Subtarget->hasB())
5457 // CHECK-NEXT: Features[Feature_HasBBit] = 1;
58 // CHECK-NEXT: return Features;
59 // CHECK-NEXT: }
60
61 // CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
62 // CHECK-NEXT: computeAvailableFunctionFeatures(const MyTargetSubtarget *Subtarget, const MachineFunction *MF) const {
63 // CHECK-NEXT: PredicateBitset Features;
64 // CHECK-NEXT: if (Subtarget->hasC())
65 // CHECK-NEXT: Features[Feature_HasCBit] = 1;
5566 // CHECK-NEXT: return Features;
5667 // CHECK-NEXT: }
5768
215226 //===- Test another simple pattern with regclass operands. ----------------===//
216227
217228 // CHECK-LABEL: if ([&]() {
218 // CHECK-NEXT: PredicateBitset ExpectedFeatures = {Feature_HasABit, Feature_HasBBit};
229 // CHECK-NEXT: PredicateBitset ExpectedFeatures = {Feature_HasABit, Feature_HasBBit, Feature_HasCBit};
219230 // CHECK-NEXT: if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
220231 // CHECK-NEXT: return false;
221232 // CHECK-NEXT: MachineInstr &MI0 = I;
246257
247258 def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),
248259 [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>,
249 Requires<[HasA, HasB]>;
260 Requires<[HasA, HasB, HasC]>;
250261
251262 //===- Test a pattern with ComplexPattern operands. -----------------------===//
252263 //
2929
3030 std::unique_ptr createInstrInfo(TargetMachine *TM) {
3131 AArch64Subtarget ST(TM->getTargetTriple(), TM->getTargetCPU(),
32 TM->getTargetFeatureString(), *TM, /* isLittle */ false);
32 TM->getTargetFeatureString(), *TM, /* isLittle */ false,
33 /* ForCodeSize */ false);
3334 return llvm::make_unique(ST);
3435 }
3536
198198 void emitCxxCapturedInsnList(raw_ostream &OS);
199199 void emitCxxCaptureStmts(raw_ostream &OS, StringRef Expr);
200200
201 void emit(raw_ostream &OS,
202 std::map
203 SubtargetFeatures);
204
205 /// Compare the priority of this object and B.
206 ///
207 /// Returns true if this object is more important than B.
208 bool isHigherPriorityThan(const RuleMatcher &B) const;
209
210 /// Report the maximum number of temporary operands needed by the rule
211 /// matcher.
212 unsigned countRendererFns() const;
213
214 // FIXME: Remove this as soon as possible
215 InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }
201 void emit(raw_ostream &OS, SubtargetFeatureInfoMap SubtargetFeatures);
202
203 /// Compare the priority of this object and B.
204 ///
205 /// Returns true if this object is more important than B.
206 bool isHigherPriorityThan(const RuleMatcher &B) const;
207
208 /// Report the maximum number of temporary operands needed by the rule
209 /// matcher.
210 unsigned countRendererFns() const;
211
212 // FIXME: Remove this as soon as possible
213 InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); }
216214 };
217215
218216 template class PredicateListMatcher {
950948
951949 /// True if the instruction can be built solely by mutating the opcode.
952950 bool canMutate() const {
951 if (OperandRenderers.size() != Matched.getNumOperands())
952 return false;
953
953954 for (const auto &Renderer : enumerate(OperandRenderers)) {
954955 if (const auto *Copy = dyn_cast(&*Renderer.value())) {
955956 const OperandMatcher &OM = Matched.getOperand(Copy->getSymbolicName());
10711072 }
10721073
10731074 void RuleMatcher::emit(raw_ostream &OS,
1074 std::map
1075 SubtargetFeatures) {
1075 SubtargetFeatureInfoMap SubtargetFeatures) {
10761076 if (Matchers.empty())
10771077 llvm_unreachable("Unexpected empty matcher!");
10781078
12171217 DenseMap ComplexPatternEquivs;
12181218
12191219 // Map of predicates to their subtarget features.
1220 std::map SubtargetFeatures;
1220 SubtargetFeatureInfoMap SubtargetFeatures;
12211221
12221222 void gatherNodeEquivs();
12231223 const CodeGenInstruction *findNodeEquiv(Record *N) const;
17121712 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
17131713 OS);
17141714 SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, OS);
1715
1716 // Separate subtarget features by how often they must be recomputed.
1717 SubtargetFeatureInfoMap ModuleFeatures;
1718 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
1719 std::inserter(ModuleFeatures, ModuleFeatures.end()),
1720 [](const SubtargetFeatureInfoMap::value_type &X) {
1721 return !X.second.mustRecomputePerFunction();
1722 });
1723 SubtargetFeatureInfoMap FunctionFeatures;
1724 std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(),
1725 std::inserter(FunctionFeatures, FunctionFeatures.end()),
1726 [](const SubtargetFeatureInfoMap::value_type &X) {
1727 return X.second.mustRecomputePerFunction();
1728 });
1729
17151730 SubtargetFeatureInfo::emitComputeAvailableFeatures(
1716 Target.getName(), "InstructionSelector", "computeAvailableFeatures",
1717 SubtargetFeatures, OS);
1731 Target.getName(), "InstructionSelector", "computeAvailableModuleFeatures",
1732 ModuleFeatures, OS);
1733 SubtargetFeatureInfo::emitComputeAvailableFeatures(
1734 Target.getName(), "InstructionSelector",
1735 "computeAvailableFunctionFeatures", FunctionFeatures, OS,
1736 "const MachineFunction *MF");
17181737
17191738 OS << "bool " << Target.getName()
17201739 << "InstructionSelector::selectImpl(MachineInstr &I) const {\n"
17211740 << " MachineFunction &MF = *I.getParent()->getParent();\n"
1722 << " const MachineRegisterInfo &MRI = MF.getRegInfo();\n";
1741 << " const MachineRegisterInfo &MRI = MF.getRegInfo();\n"
1742 << " // FIXME: This should be computed on a per-function basis rather than per-insn.\n"
1743 << " AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, &MF);\n"
1744 << " const PredicateBitset AvailableFeatures = getAvailableFeatures();\n";
17231745
17241746 for (auto &Rule : Rules) {
17251747 Rule.emit(OS, SubtargetFeatures);
17291751 OS << " return false;\n"
17301752 << "}\n"
17311753 << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
1754
1755 OS << "#ifdef GET_GLOBALISEL_PREDICATES_DECL\n"
1756 << "PredicateBitset AvailableModuleFeatures;\n"
1757 << "mutable PredicateBitset AvailableFunctionFeatures;\n"
1758 << "PredicateBitset getAvailableFeatures() const {\n"
1759 << " return AvailableModuleFeatures | AvailableFunctionFeatures;\n"
1760 << "}\n"
1761 << "PredicateBitset\n"
1762 << "computeAvailableModuleFeatures(const " << Target.getName()
1763 << "Subtarget *Subtarget) const;\n"
1764 << "PredicateBitset\n"
1765 << "computeAvailableFunctionFeatures(const " << Target.getName()
1766 << "Subtarget *Subtarget,\n"
1767 << " const MachineFunction *MF) const;\n"
1768 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_DECL\n";
1769
1770 OS << "#ifdef GET_GLOBALISEL_PREDICATES_INIT\n"
1771 << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"
1772 << "AvailableFunctionFeatures()\n"
1773 << "#endif // ifdef GET_GLOBALISEL_PREDICATES_INIT\n";
17321774 }
17331775
17341776 void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
4444 }
4545
4646 void SubtargetFeatureInfo::emitSubtargetFeatureFlagEnumeration(
47 std::map &SubtargetFeatures,
48 raw_ostream &OS) {
47 SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
4948 OS << "// Flags for subtarget features that participate in "
5049 << "instruction matching.\n";
5150 OS << "enum SubtargetFeatureFlag : "
5958 }
6059
6160 void SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(
62 std::map &SubtargetFeatures,
63 raw_ostream &OS) {
61 SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
6462 OS << "// Bits for subtarget features that participate in "
6563 << "instruction matching.\n";
6664 OS << "enum SubtargetFeatureBits : "
7371 }
7472
7573 void SubtargetFeatureInfo::emitNameTable(
76 std::map &SubtargetFeatures,
77 raw_ostream &OS) {
74 SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
7875 // Need to sort the name table so that lookup by the log of the enum value
7976 // gives the proper name. More specifically, for a feature of value 1<
8077 // SubtargetFeatureNames[n] should be the name of the feature.
10198
10299 void SubtargetFeatureInfo::emitComputeAvailableFeatures(
103100 StringRef TargetName, StringRef ClassName, StringRef FuncName,
104 std::map &SubtargetFeatures,
105 raw_ostream &OS) {
101 SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS,
102 StringRef ExtraParams) {
106103 OS << "PredicateBitset " << TargetName << ClassName << "::\n"
107 << FuncName << "(const MachineFunction *MF, const " << TargetName
108 << "Subtarget *Subtarget) const {\n";
104 << FuncName << "(const " << TargetName << "Subtarget *Subtarget";
105 if (!ExtraParams.empty())
106 OS << ", " << ExtraParams;
107 OS << ") const {\n";
109108 OS << " PredicateBitset Features;\n";
110109 for (const auto &SF : SubtargetFeatures) {
111110 const SubtargetFeatureInfo &SFI = SF.second;
119118
120119 void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
121120 StringRef TargetName, StringRef ClassName, StringRef FuncName,
122 std::map &SubtargetFeatures,
123 raw_ostream &OS) {
121 SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
124122 OS << "uint64_t " << TargetName << ClassName << "::\n"
125123 << FuncName << "(const FeatureBitset& FB) const {\n";
126124 OS << " uint64_t Features = 0;\n";
2020 class Record;
2121 class RecordKeeper;
2222
23 struct SubtargetFeatureInfo;
24 using SubtargetFeatureInfoMap = std::map;
25
2326 /// Helper class for storing information on a subtarget feature which
2427 /// participates in instruction matching.
2528 struct SubtargetFeatureInfo {
4245 return "Feature_" + TheDef->getName().str() + "Bit";
4346 }
4447
48 bool mustRecomputePerFunction() const {
49 return TheDef->getValueAsBit("RecomputePerFunction");
50 }
51
4552 void dump() const;
4653 static std::vector>
4754 getAll(const RecordKeeper &Records);
5158 /// This version emits the bit value for the feature and is therefore limited
5259 /// to 64 feature bits.
5360 static void emitSubtargetFeatureFlagEnumeration(
54 std::map
55 &SubtargetFeatures,
56 raw_ostream &OS);
61 SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS);
5762
5863 /// Emit the subtarget feature flag definitions.
5964 ///
6065 /// This version emits the bit index for the feature and can therefore support
6166 /// more than 64 feature bits.
62 static void emitSubtargetFeatureBitEnumeration(
63 std::map
64 &SubtargetFeatures,
65 raw_ostream &OS);
67 static void
68 emitSubtargetFeatureBitEnumeration(SubtargetFeatureInfoMap &SubtargetFeatures,
69 raw_ostream &OS);
6670
67 static void emitNameTable(std::map
68 LessRecordByID> &SubtargetFeatures,
71 static void emitNameTable(SubtargetFeatureInfoMap &SubtargetFeatures,
6972 raw_ostream &OS);
7073
7174 /// Emit the function to compute the list of available features given a
8184 /// \param FuncName The name of the function to emit.
8285 /// \param SubtargetFeatures A map of TableGen records to the
8386 /// SubtargetFeatureInfo equivalent.
84 static void emitComputeAvailableFeatures(
85 StringRef TargetName, StringRef ClassName, StringRef FuncName,
86 std::map
87 &SubtargetFeatures,
88 raw_ostream &OS);
87 /// \param ExtraParams Additional arguments to the generated function.
88 static void
89 emitComputeAvailableFeatures(StringRef TargetName, StringRef ClassName,
90 StringRef FuncName,
91 SubtargetFeatureInfoMap &SubtargetFeatures,
92 raw_ostream &OS, StringRef ExtraParams = "");
8993
9094 /// Emit the function to compute the list of available features given a
9195 /// subtarget.
102106 /// SubtargetFeatureInfo equivalent.
103107 static void emitComputeAssemblerAvailableFeatures(
104108 StringRef TargetName, StringRef ClassName, StringRef FuncName,
105 std::map
106 &SubtargetFeatures,
107 raw_ostream &OS);
109 SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS);
108110 };
109111 } // end namespace llvm
110112