diff options
Diffstat (limited to 'llvm/utils')
| -rw-r--r-- | llvm/utils/TableGen/GlobalISelEmitter.cpp | 69 |
1 files changed, 44 insertions, 25 deletions
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index d1821b64dd8..246af4c3a38 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -182,14 +182,6 @@ static Error failedImport(const Twine &Reason) { static Error isTrivialOperatorNode(const TreePatternNode *N) { std::string Explanation = ""; std::string Separator = ""; - if (N->isLeaf()) { - if (isa<IntInit>(N->getLeafValue())) - return Error::success(); - - Explanation = "Is a leaf"; - Separator = ", "; - } - if (N->hasAnyPredicate()) { Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")"; Separator = ", "; @@ -200,7 +192,7 @@ static Error isTrivialOperatorNode(const TreePatternNode *N) { Separator = ", "; } - if (!N->isLeaf() && !N->hasAnyPredicate() && !N->getTransformFn()) + if (!N->hasAnyPredicate() && !N->getTransformFn()) return Error::success(); return failedImport(Explanation); @@ -2287,8 +2279,42 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { return failedImport("Src pattern root isn't a trivial operator (" + toString(std::move(Err)) + ")"); - if (Dst->isLeaf()) + InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src->getName()); + unsigned TempOpIdx = 0; + auto InsnMatcherOrError = + createAndImportSelDAGMatcher(InsnMatcherTemp, Src, TempOpIdx); + if (auto Error = InsnMatcherOrError.takeError()) + return std::move(Error); + InstructionMatcher &InsnMatcher = InsnMatcherOrError.get(); + + if (Dst->isLeaf()) { + Record *RCDef = getInitValueAsRegClass(Dst->getLeafValue()); + + const CodeGenRegisterClass &RC = Target.getRegisterClass(RCDef); + if (RCDef) { + // We need to replace the def and all its uses with the specified + // operand. However, we must also insert COPY's wherever needed. + // For now, emit a copy and let the register allocator clean up. + auto &DstI = Target.getInstruction(RK.getDef("COPY")); + const auto &DstIOperand = DstI.Operands[0]; + + OperandMatcher &OM0 = InsnMatcher.getOperand(0); + OM0.setSymbolicName(DstIOperand.Name); + OM0.addPredicate<RegisterBankOperandMatcher>(RC); + + auto &DstMIBuilder = M.addAction<BuildMIAction>(0, &DstI, InsnMatcher); + DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher, DstIOperand.Name); + DstMIBuilder.addRenderer<CopyRenderer>(0, InsnMatcher, Dst->getName()); + M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC); + + // We're done with this pattern! It's eligible for GISel emission; return + // it. + ++NumPatternImported; + return std::move(M); + } + return failedImport("Dst pattern root isn't a known leaf"); + } // Start with the defined operands (i.e., the results of the root operator). Record *DstOp = Dst->getOperator(); @@ -2301,14 +2327,6 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { to_string(Src->getExtTypes().size()) + " def(s) vs " + to_string(DstI.Operands.NumDefs) + " def(s))"); - InstructionMatcher &InsnMatcherTemp = M.addInstructionMatcher(Src->getName()); - unsigned TempOpIdx = 0; - auto InsnMatcherOrError = - createAndImportSelDAGMatcher(InsnMatcherTemp, Src, TempOpIdx); - if (auto Error = InsnMatcherOrError.takeError()) - return std::move(Error); - InstructionMatcher &InsnMatcher = InsnMatcherOrError.get(); - // The root of the match also has constraints on the register bank so that it // matches the result instruction. unsigned OpIdx = 0; @@ -2537,13 +2555,14 @@ void GlobalISelEmitter::run(raw_ostream &OS) { // for the matcher to reference them with. std::vector<LLTCodeGen> TypeObjects = { LLT::scalar(8), LLT::scalar(16), LLT::scalar(32), - LLT::scalar(64), LLT::scalar(80), LLT::vector(8, 1), - LLT::vector(16, 1), LLT::vector(32, 1), LLT::vector(64, 1), - LLT::vector(8, 8), LLT::vector(16, 8), LLT::vector(32, 8), - LLT::vector(64, 8), LLT::vector(4, 16), LLT::vector(8, 16), - LLT::vector(16, 16), LLT::vector(32, 16), LLT::vector(2, 32), - LLT::vector(4, 32), LLT::vector(8, 32), LLT::vector(16, 32), - LLT::vector(2, 64), LLT::vector(4, 64), LLT::vector(8, 64), + LLT::scalar(64), LLT::scalar(80), LLT::scalar(128), + LLT::vector(8, 1), LLT::vector(16, 1), LLT::vector(32, 1), + LLT::vector(64, 1), LLT::vector(8, 8), LLT::vector(16, 8), + LLT::vector(32, 8), LLT::vector(64, 8), LLT::vector(4, 16), + LLT::vector(8, 16), LLT::vector(16, 16), LLT::vector(32, 16), + LLT::vector(2, 32), LLT::vector(4, 32), LLT::vector(8, 32), + LLT::vector(16, 32), LLT::vector(2, 64), LLT::vector(4, 64), + LLT::vector(8, 64), }; std::sort(TypeObjects.begin(), TypeObjects.end()); OS << "enum {\n"; |

