Skip to content

Commit 49e19e9

Browse files
author
Dan Gohman
committed
Factor out the predicate check code from DAGISelEmitter.cpp
and use it in FastISelEmitter.cpp, and make FastISel subtarget aware. Among other things, this lets it work properly on x86 targets that don't have SSE, where it successfully selects x87 instructions. llvm-svn: 55156
1 parent 24c0154 commit 49e19e9

File tree

8 files changed

+111
-54
lines changed

8 files changed

+111
-54
lines changed

llvm/include/llvm/CodeGen/FastISel.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,21 @@ class MachineRegisterInfo;
2626
class TargetData;
2727
class TargetInstrInfo;
2828
class TargetLowering;
29+
class TargetMachine;
2930
class TargetRegisterClass;
3031

3132
/// FastISel - This is a fast-path instruction selection class that
3233
/// generates poor code and doesn't support illegal types or non-trivial
3334
/// lowering, but runs quickly.
3435
class FastISel {
36+
protected:
3537
MachineBasicBlock *MBB;
3638
MachineFunction &MF;
3739
MachineRegisterInfo &MRI;
40+
const TargetMachine &TM;
3841
const TargetData &TD;
3942
const TargetInstrInfo &TII;
40-
TargetLowering &TLI;
43+
const TargetLowering &TLI;
4144

4245
public:
4346
/// SelectInstructions - Do "fast" instruction selection over the

llvm/lib/CodeGen/SelectionDAG/FastISel.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,12 @@ FastISel::SelectInstructions(BasicBlock::iterator Begin,
220220
}
221221

222222
FastISel::FastISel(MachineFunction &mf)
223-
: MF(mf), MRI(mf.getRegInfo()),
224-
TD(*mf.getTarget().getTargetData()),
225-
TII(*mf.getTarget().getInstrInfo()),
226-
TLI(*mf.getTarget().getTargetLowering()) {
223+
: MF(mf),
224+
MRI(mf.getRegInfo()),
225+
TM(mf.getTarget()),
226+
TD(*TM.getTargetData()),
227+
TII(*TM.getInstrInfo()),
228+
TLI(*TM.getTargetLowering()) {
227229
}
228230

229231
FastISel::~FastISel() {}

llvm/lib/Target/X86/X86FastISel.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@
1717
#include "X86RegisterInfo.h"
1818
#include "X86ISelLowering.h"
1919
#include "X86FastISel.h"
20+
#include "X86TargetMachine.h"
2021
#include "X86GenFastISel.inc"

llvm/test/CodeGen/X86/fast-isel.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: llvm-as < %s | llc -fast-isel -march=x86 -mattr=sse2
1+
; RUN: llvm-as < %s | llc -fast-isel -march=x86
22

33
; This tests very minimal fast-isel functionality.
44

llvm/utils/TableGen/CodeGenDAGPatterns.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,33 @@ void DumpDepVars(MultipleUseVarSet &DepVars) {
140140
}
141141
}
142142

143+
//===----------------------------------------------------------------------===//
144+
// PatternToMatch implementation
145+
//
146+
147+
/// getPredicateCheck - Return a single string containing all of this
148+
/// pattern's predicates concatenated with "&&" operators.
149+
///
150+
std::string PatternToMatch::getPredicateCheck() const {
151+
std::string PredicateCheck;
152+
for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
153+
if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
154+
Record *Def = Pred->getDef();
155+
if (!Def->isSubClassOf("Predicate")) {
156+
#ifndef NDEBUG
157+
Def->dump();
158+
#endif
159+
assert(0 && "Unknown predicate type!");
160+
}
161+
if (!PredicateCheck.empty())
162+
PredicateCheck += " && ";
163+
PredicateCheck += "(" + Def->getValueAsString("CondString") + ")";
164+
}
165+
}
166+
167+
return PredicateCheck;
168+
}
169+
143170
//===----------------------------------------------------------------------===//
144171
// SDTypeConstraint implementation
145172
//

llvm/utils/TableGen/CodeGenDAGPatterns.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,8 @@ struct PatternToMatch {
444444
TreePatternNode *getDstPattern() const { return DstPattern; }
445445
const std::vector<Record*> &getDstRegs() const { return Dstregs; }
446446
unsigned getAddedComplexity() const { return AddedComplexity; }
447+
448+
std::string getPredicateCheck() const;
447449
};
448450

449451

llvm/utils/TableGen/DAGISelEmitter.cpp

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ class PatternCodeEmitter {
317317
CodeGenDAGPatterns &CGP;
318318

319319
// Predicates.
320-
ListInit *Predicates;
320+
std::string PredicateCheck;
321321
// Pattern cost.
322322
unsigned Cost;
323323
// Instruction selector pattern.
@@ -395,15 +395,15 @@ class PatternCodeEmitter {
395395
VTNo++;
396396
}
397397
public:
398-
PatternCodeEmitter(CodeGenDAGPatterns &cgp, ListInit *preds,
398+
PatternCodeEmitter(CodeGenDAGPatterns &cgp, std::string predcheck,
399399
TreePatternNode *pattern, TreePatternNode *instr,
400400
std::vector<std::pair<unsigned, std::string> > &gc,
401401
std::set<std::string> &gd,
402402
std::vector<std::string> &to,
403403
std::vector<std::string> &tv,
404404
bool &oiv,
405405
unsigned &niro)
406-
: CGP(cgp), Predicates(preds), Pattern(pattern), Instruction(instr),
406+
: CGP(cgp), PredicateCheck(predcheck), Pattern(pattern), Instruction(instr),
407407
GeneratedCode(gc), GeneratedDecl(gd),
408408
TargetOpcodes(to), TargetVTs(tv),
409409
OutputIsVariadic(oiv), NumInputRootOps(niro),
@@ -431,22 +431,6 @@ class PatternCodeEmitter {
431431
if (DisablePatternForFastISel(N, CGP))
432432
emitCheck("!Fast");
433433

434-
std::string PredicateCheck;
435-
for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
436-
if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
437-
Record *Def = Pred->getDef();
438-
if (!Def->isSubClassOf("Predicate")) {
439-
#ifndef NDEBUG
440-
Def->dump();
441-
#endif
442-
assert(0 && "Unknown predicate type!");
443-
}
444-
if (!PredicateCheck.empty())
445-
PredicateCheck += " && ";
446-
PredicateCheck += "(" + Def->getValueAsString("CondString") + ")";
447-
}
448-
}
449-
450434
emitCheck(PredicateCheck);
451435
}
452436

@@ -1412,7 +1396,7 @@ void DAGISelEmitter::GenerateCodeForPattern(const PatternToMatch &Pattern,
14121396
OutputIsVariadic = false;
14131397
NumInputRootOps = 0;
14141398

1415-
PatternCodeEmitter Emitter(CGP, Pattern.getPredicates(),
1399+
PatternCodeEmitter Emitter(CGP, Pattern.getPredicateCheck(),
14161400
Pattern.getSrcPattern(), Pattern.getDstPattern(),
14171401
GeneratedCode, GeneratedDecl,
14181402
TargetOpcodes, TargetVTs,

llvm/utils/TableGen/FastISelEmitter.cpp

Lines changed: 66 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,11 @@ void FastISelEmitter::run(std::ostream &OS) {
175175
OS << "namespace " << InstNS.substr(0, InstNS.size() - 2) << " {\n";
176176
OS << "\n";
177177

178-
typedef std::map<MVT::SimpleValueType, InstructionMemo> TypeMap;
179-
typedef std::map<std::string, TypeMap> OpcodeTypeMap;
180-
typedef std::map<OperandsSignature, OpcodeTypeMap> OperandsOpcodeTypeMap;
181-
OperandsOpcodeTypeMap SimplePatterns;
178+
typedef std::map<std::string, InstructionMemo> PredMap;
179+
typedef std::map<MVT::SimpleValueType, PredMap> TypePredMap;
180+
typedef std::map<std::string, TypePredMap> OpcodeTypePredMap;
181+
typedef std::map<OperandsSignature, OpcodeTypePredMap> OperandsOpcodeTypePredMap;
182+
OperandsOpcodeTypePredMap SimplePatterns;
182183

183184
for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
184185
E = CGP.ptm_end(); I != E; ++I) {
@@ -230,27 +231,32 @@ void FastISelEmitter::run(std::ostream &OS) {
230231
if (!Operands.initialize(InstPatNode, Target, VT, DstRC))
231232
continue;
232233

234+
// Get the predicate that guards this pattern.
235+
std::string PredicateCheck = Pattern.getPredicateCheck();
236+
233237
// Ok, we found a pattern that we can handle. Remember it.
234238
InstructionMemo Memo = {
235239
Pattern.getDstPattern()->getOperator()->getName(),
236240
DstRC
237241
};
238-
SimplePatterns[Operands][OpcodeName][VT] = Memo;
242+
assert(!SimplePatterns[Operands][OpcodeName][VT].count(PredicateCheck) &&
243+
"Duplicate pattern!");
244+
SimplePatterns[Operands][OpcodeName][VT][PredicateCheck] = Memo;
239245
}
240246

241247
// Declare the target FastISel class.
242248
OS << "class FastISel : public llvm::FastISel {\n";
243-
for (OperandsOpcodeTypeMap::const_iterator OI = SimplePatterns.begin(),
249+
for (OperandsOpcodeTypePredMap::const_iterator OI = SimplePatterns.begin(),
244250
OE = SimplePatterns.end(); OI != OE; ++OI) {
245251
const OperandsSignature &Operands = OI->first;
246-
const OpcodeTypeMap &OTM = OI->second;
252+
const OpcodeTypePredMap &OTM = OI->second;
247253

248-
for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
254+
for (OpcodeTypePredMap::const_iterator I = OTM.begin(), E = OTM.end();
249255
I != E; ++I) {
250256
const std::string &Opcode = I->first;
251-
const TypeMap &TM = I->second;
257+
const TypePredMap &TM = I->second;
252258

253-
for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
259+
for (TypePredMap::const_iterator TI = TM.begin(), TE = TM.end();
254260
TI != TE; ++TI) {
255261
MVT::SimpleValueType VT = TI->first;
256262

@@ -279,8 +285,19 @@ void FastISelEmitter::run(std::ostream &OS) {
279285
Operands.PrintParameters(OS);
280286
OS << ");\n";
281287
}
288+
OS << "\n";
289+
290+
// Declare the Subtarget member, which is used for predicate checks.
291+
OS << " const " << InstNS.substr(0, InstNS.size() - 2)
292+
<< "Subtarget *Subtarget;\n";
293+
OS << "\n";
294+
295+
// Declare the constructor.
282296
OS << "public:\n";
283-
OS << " explicit FastISel(MachineFunction &mf) : llvm::FastISel(mf) {}\n";
297+
OS << " explicit FastISel(MachineFunction &mf)\n";
298+
OS << " : llvm::FastISel(mf),\n";
299+
OS << " Subtarget(&TM.getSubtarget<" << InstNS.substr(0, InstNS.size() - 2)
300+
<< "Subtarget>()) {}\n";
284301
OS << "};\n";
285302
OS << "\n";
286303

@@ -291,40 +308,61 @@ void FastISelEmitter::run(std::ostream &OS) {
291308
OS << "\n";
292309

293310
// Now emit code for all the patterns that we collected.
294-
for (OperandsOpcodeTypeMap::const_iterator OI = SimplePatterns.begin(),
311+
for (OperandsOpcodeTypePredMap::const_iterator OI = SimplePatterns.begin(),
295312
OE = SimplePatterns.end(); OI != OE; ++OI) {
296313
const OperandsSignature &Operands = OI->first;
297-
const OpcodeTypeMap &OTM = OI->second;
314+
const OpcodeTypePredMap &OTM = OI->second;
298315

299-
for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
316+
for (OpcodeTypePredMap::const_iterator I = OTM.begin(), E = OTM.end();
300317
I != E; ++I) {
301318
const std::string &Opcode = I->first;
302-
const TypeMap &TM = I->second;
319+
const TypePredMap &TM = I->second;
303320

304321
OS << "// FastEmit functions for " << Opcode << ".\n";
305322
OS << "\n";
306323

307324
// Emit one function for each opcode,type pair.
308-
for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
325+
for (TypePredMap::const_iterator TI = TM.begin(), TE = TM.end();
309326
TI != TE; ++TI) {
310327
MVT::SimpleValueType VT = TI->first;
311-
const InstructionMemo &Memo = TI->second;
312-
328+
const PredMap &PM = TI->second;
329+
bool HasPred = false;
330+
313331
OS << "unsigned FastISel::FastEmit_"
314332
<< getLegalCName(Opcode)
315333
<< "_" << getLegalCName(getName(VT)) << "_";
316334
Operands.PrintManglingSuffix(OS);
317335
OS << "(";
318336
Operands.PrintParameters(OS);
319337
OS << ") {\n";
320-
OS << " return FastEmitInst_";
321-
Operands.PrintManglingSuffix(OS);
322-
OS << "(" << InstNS << Memo.Name << ", ";
323-
OS << InstNS << Memo.RC->getName() << "RegisterClass";
324-
if (!Operands.empty())
325-
OS << ", ";
326-
Operands.PrintArguments(OS);
327-
OS << ");\n";
338+
339+
// Emit code for each possible instruction. There may be
340+
// multiple if there are subtarget concerns.
341+
for (PredMap::const_iterator PI = PM.begin(), PE = PM.end();
342+
PI != PE; ++PI) {
343+
std::string PredicateCheck = PI->first;
344+
const InstructionMemo &Memo = PI->second;
345+
346+
if (PredicateCheck.empty()) {
347+
assert(!HasPred && "Multiple instructions match, at least one has "
348+
"a predicate and at least one doesn't!");
349+
} else {
350+
OS << " if (" + PredicateCheck + ")\n";
351+
OS << " ";
352+
HasPred = true;
353+
}
354+
OS << " return FastEmitInst_";
355+
Operands.PrintManglingSuffix(OS);
356+
OS << "(" << InstNS << Memo.Name << ", ";
357+
OS << InstNS << Memo.RC->getName() << "RegisterClass";
358+
if (!Operands.empty())
359+
OS << ", ";
360+
Operands.PrintArguments(OS);
361+
OS << ");\n";
362+
}
363+
// Return 0 if none of the predicates were satisfied.
364+
if (HasPred)
365+
OS << " return 0;\n";
328366
OS << "}\n";
329367
OS << "\n";
330368
}
@@ -339,7 +377,7 @@ void FastISelEmitter::run(std::ostream &OS) {
339377
Operands.PrintParameters(OS);
340378
OS << ") {\n";
341379
OS << " switch (VT) {\n";
342-
for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
380+
for (TypePredMap::const_iterator TI = TM.begin(), TE = TM.end();
343381
TI != TE; ++TI) {
344382
MVT::SimpleValueType VT = TI->first;
345383
std::string TypeName = getName(VT);
@@ -366,7 +404,7 @@ void FastISelEmitter::run(std::ostream &OS) {
366404
Operands.PrintParameters(OS);
367405
OS << ") {\n";
368406
OS << " switch (Opcode) {\n";
369-
for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
407+
for (OpcodeTypePredMap::const_iterator I = OTM.begin(), E = OTM.end();
370408
I != E; ++I) {
371409
const std::string &Opcode = I->first;
372410

0 commit comments

Comments
 (0)