diff options
author | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2018-10-31 12:28:05 +0000 |
---|---|---|
committer | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2018-10-31 12:28:05 +0000 |
commit | 3d2b7176fc17bb4307169984120e682de086738d (patch) | |
tree | f91a4cc4a33bfa1ab87facce11d703eaeb683377 /llvm/utils/TableGen/PredicateExpander.cpp | |
parent | ea35455d9eedc047b06254505d44ca8368a3e1c8 (diff) | |
download | bcm5719-llvm-3d2b7176fc17bb4307169984120e682de086738d.tar.gz bcm5719-llvm-3d2b7176fc17bb4307169984120e682de086738d.zip |
[tblgen][PredicateExpander] Add the ability to describe more complex constraints on instruction operands.
Before this patch, class PredicateExpander only knew how to expand simple
predicates that performed checks on instruction operands.
In particular, the new scheduling predicate syntax was not rich enough to
express checks like this one:
Foo(MI->getOperand(0).getImm()) == ExpectedVal;
Here, the immediate operand value at index zero is passed in input to function
Foo, and ExpectedVal is compared against the value returned by function Foo.
While this predicate pattern doesn't show up in any X86 model, it shows up in
other upstream targets. So, being able to support those predicates is
fundamental if we want to be able to modernize all the scheduling models
upstream.
With this patch, we allow users to specify if a register/immediate operand value
needs to be passed in input to a function as part of the predicate check. Now,
register/immediate operand checks all derive from base class CheckOperandBase.
This patch also changes where TIIPredicate definitions are expanded by the
instructon info emitter. Before, definitions were expanded in class
XXXGenInstrInfo (where XXX is a target name).
With the introduction of this new syntax, we may want to have TIIPredicates
expanded directly in XXXInstrInfo. That is because functions used by the new
operand predicates may only exist in the derived class (i.e. XXXInstrInfo).
This patch is a non functional change for the existing scheduling models.
In future, we will be able to use this richer syntax to better describe complex
scheduling predicates, and expose them to llvm-mca.
Differential Revision: https://reviews.llvm.org/D53880
llvm-svn: 345714
Diffstat (limited to 'llvm/utils/TableGen/PredicateExpander.cpp')
-rw-r--r-- | llvm/utils/TableGen/PredicateExpander.cpp | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/llvm/utils/TableGen/PredicateExpander.cpp b/llvm/utils/TableGen/PredicateExpander.cpp index 83f67c023e5..ad7bf60caab 100644 --- a/llvm/utils/TableGen/PredicateExpander.cpp +++ b/llvm/utils/TableGen/PredicateExpander.cpp @@ -20,23 +20,43 @@ void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; } void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; } void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex, - int ImmVal) { + int ImmVal, + StringRef FunctionMapper) { + if (!FunctionMapper.empty()) + OS << FunctionMapper << "("; OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex - << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal; + << ").getImm()"; + OS << (FunctionMapper.empty() ? " " : ") "); + OS << (shouldNegate() ? "!= " : "== ") << ImmVal; } void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex, - StringRef ImmVal) { + StringRef ImmVal, + StringRef FunctionMapper) { + if (!FunctionMapper.empty()) + OS << FunctionMapper << "("; OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex - << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal; + << ").getImm()"; + + OS << (FunctionMapper.empty() ? "" : ")"); + if (ImmVal.empty()) + return; + OS << (shouldNegate() ? " != " : " == ") << ImmVal; } void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex, - const Record *Reg) { + const Record *Reg, + StringRef FunctionMapper) { assert(Reg->isSubClassOf("Register") && "Expected a register Record!"); + if (!FunctionMapper.empty()) + OS << FunctionMapper << "("; OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex - << ").getReg() " << (shouldNegate() ? "!= " : "== "); + << ").getReg()"; + OS << (FunctionMapper.empty() ? "" : ")"); + if (!Reg) + return; + OS << (shouldNegate() ? " != " : " == "); const StringRef Str = Reg->getValueAsString("Namespace"); if (!Str.empty()) OS << Str << "::"; @@ -137,7 +157,7 @@ void PredicateExpander::expandPredicateSequence(raw_ostream &OS, void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS, StringRef MethodName) { OS << (shouldNegate() ? "!" : ""); - OS << TargetName << (shouldExpandForMC() ? "_MC::" : "GenInstrInfo::"); + OS << TargetName << (shouldExpandForMC() ? "_MC::" : "InstrInfo::"); OS << MethodName << (isByRef() ? "(MI)" : "(*MI)"); } @@ -266,18 +286,30 @@ void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) { if (Rec->isSubClassOf("CheckRegOperand")) return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"), - Rec->getValueAsDef("Reg")); + Rec->getValueAsDef("Reg"), + Rec->getValueAsString("FunctionMapper")); + + if (Rec->isSubClassOf("CheckRegOperandSimple")) + return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"), + nullptr, + Rec->getValueAsString("FunctionMapper")); if (Rec->isSubClassOf("CheckInvalidRegOperand")) return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex")); if (Rec->isSubClassOf("CheckImmOperand")) return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), - Rec->getValueAsInt("ImmVal")); + Rec->getValueAsInt("ImmVal"), + Rec->getValueAsString("FunctionMapper")); if (Rec->isSubClassOf("CheckImmOperand_s")) return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), - Rec->getValueAsString("ImmVal")); + Rec->getValueAsString("ImmVal"), + Rec->getValueAsString("FunctionMapper")); + + if (Rec->isSubClassOf("CheckImmOperandSimple")) + return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), "", + Rec->getValueAsString("FunctionMapper")); if (Rec->isSubClassOf("CheckSameRegOperand")) return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"), |