diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-05-17 20:22:39 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-05-17 20:22:39 +0000 |
commit | 7af96fb3afd6725a2824a0a5ca5dad34e5e0b056 (patch) | |
tree | 6661ffbabf869009597684462f5a3df3beccc952 /utils/TableGen/GlobalISelEmitter.cpp | |
parent | 6b3f41ed88e8e440e11a4fbf20b6600529f80049 (diff) |
Diffstat (limited to 'utils/TableGen/GlobalISelEmitter.cpp')
-rw-r--r-- | utils/TableGen/GlobalISelEmitter.cpp | 124 |
1 files changed, 73 insertions, 51 deletions
diff --git a/utils/TableGen/GlobalISelEmitter.cpp b/utils/TableGen/GlobalISelEmitter.cpp index 65a1ea2f0f21d..dc022fe1ceb25 100644 --- a/utils/TableGen/GlobalISelEmitter.cpp +++ b/utils/TableGen/GlobalISelEmitter.cpp @@ -775,6 +775,8 @@ public: void emitCxxCaptureStmts(raw_ostream &OS, RuleMatcher &Rule, StringRef OperandExpr) const override { OS << "if (!" << OperandExpr + ".isReg())\n" + << " return false;\n" + << "if (TRI.isPhysicalRegister(" << OperandExpr + ".getReg()))\n" << " return false;\n"; std::string InsnVarName = Rule.defineInsnVar( OS, *InsnMatcher, @@ -1242,6 +1244,8 @@ private: Error importExplicitUseRenderer(BuildMIAction &DstMIBuilder, TreePatternNode *DstChild, const InstructionMatcher &InsnMatcher) const; + Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder, + DagInit *DefaultOps) const; Error importImplicitDefRenderers(BuildMIAction &DstMIBuilder, const std::vector<Record *> &ImplicitDefs) const; @@ -1321,8 +1325,27 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher( // Match the used operands (i.e. the children of the operator). for (unsigned i = 0, e = Src->getNumChildren(); i != e; ++i) { - if (auto Error = importChildMatcher(InsnMatcher, Src->getChild(i), OpIdx++, - TempOpIdx)) + TreePatternNode *SrcChild = Src->getChild(i); + + // For G_INTRINSIC, the operand immediately following the defs is an + // intrinsic ID. + if (SrcGI.TheDef->getName() == "G_INTRINSIC" && i == 0) { + if (!SrcChild->isLeaf()) + return failedImport("Expected IntInit containing intrinsic ID"); + + if (IntInit *SrcChildIntInit = + dyn_cast<IntInit>(SrcChild->getLeafValue())) { + OperandMatcher &OM = + InsnMatcher.addOperand(OpIdx++, SrcChild->getName(), TempOpIdx); + OM.addPredicate<IntOperandMatcher>(SrcChildIntInit->getValue()); + continue; + } + + return failedImport("Expected IntInit containing instrinsic ID)"); + } + + if (auto Error = + importChildMatcher(InsnMatcher, SrcChild, OpIdx++, TempOpIdx)) return std::move(Error); } @@ -1357,7 +1380,7 @@ Error GlobalISelEmitter::importChildMatcher(InstructionMatcher &InsnMatcher, auto OpTyOrNone = MVTToLLT(ChildTypes.front().getConcrete()); if (!OpTyOrNone) - return failedImport("Src operand has an unsupported type"); + return failedImport("Src operand has an unsupported type (" + to_string(*SrcChild) + ")"); OM.addPredicate<LLTOperandMatcher>(*OpTyOrNone); // Check for nested instructions. @@ -1509,59 +1532,23 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer( DstMIBuilder.addRenderer<CopyRenderer>(InsnMatcher, DstIOperand.Name); } - // Figure out which operands need defaults inserted. Operands that subclass - // OperandWithDefaultOps are considered from left to right until we have - // enough operands to render the instruction. - SmallSet<unsigned, 2> DefaultOperands; - unsigned DstINumUses = DstI.Operands.size() - DstI.Operands.NumDefs; - unsigned NumDefaultOperands = 0; - for (unsigned I = 0; I < DstINumUses && - DstINumUses > Dst->getNumChildren() + NumDefaultOperands; - ++I) { - const auto &DstIOperand = DstI.Operands[DstI.Operands.NumDefs + I]; - if (DstIOperand.Rec->isSubClassOf("OperandWithDefaultOps")) { - DefaultOperands.insert(I); - NumDefaultOperands += - DstIOperand.Rec->getValueAsDag("DefaultOps")->getNumArgs(); - } - } - if (DstINumUses > Dst->getNumChildren() + DefaultOperands.size()) - return failedImport("Insufficient operands supplied and default ops " - "couldn't make up the shortfall"); - if (DstINumUses < Dst->getNumChildren() + DefaultOperands.size()) - return failedImport("Too many operands supplied"); - // Render the explicit uses. unsigned Child = 0; + unsigned DstINumUses = DstI.Operands.size() - DstI.Operands.NumDefs; + unsigned NumDefaultOps = 0; for (unsigned I = 0; I != DstINumUses; ++I) { - // If we need to insert default ops here, then do so. - if (DefaultOperands.count(I)) { - const auto &DstIOperand = DstI.Operands[DstI.Operands.NumDefs + I]; + const auto &DstIOperand = DstI.Operands[DstI.Operands.NumDefs + I]; + // If the operand has default values, introduce them now. + // FIXME: Until we have a decent test case that dictates we should do + // otherwise, we're going to assume that operands with default values cannot + // be specified in the patterns. Therefore, adding them will not cause us to + // end up with too many rendered operands. + if (DstIOperand.Rec->isSubClassOf("OperandWithDefaultOps")) { DagInit *DefaultOps = DstIOperand.Rec->getValueAsDag("DefaultOps"); - for (const auto *DefaultOp : DefaultOps->args()) { - // Look through ValueType operators. - if (const DagInit *DefaultDagOp = dyn_cast<DagInit>(DefaultOp)) { - if (const DefInit *DefaultDagOperator = - dyn_cast<DefInit>(DefaultDagOp->getOperator())) { - if (DefaultDagOperator->getDef()->isSubClassOf("ValueType")) - DefaultOp = DefaultDagOp->getArg(0); - } - } - - if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) { - DstMIBuilder.addRenderer<AddRegisterRenderer>(DefaultDefOp->getDef()); - continue; - } - - if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) { - DstMIBuilder.addRenderer<ImmRenderer>(DefaultIntOp->getValue()); - continue; - } - - return failedImport("Could not add default op"); - } - + if (auto Error = importDefaultOperandRenderers(DstMIBuilder, DefaultOps)) + return std::move(Error); + ++NumDefaultOps; continue; } @@ -1571,9 +1558,44 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer( ++Child; } + if (NumDefaultOps + Dst->getNumChildren() != DstINumUses) + return failedImport("Expected " + llvm::to_string(DstINumUses) + + " used operands but found " + + llvm::to_string(Dst->getNumChildren()) + + " explicit ones and " + llvm::to_string(NumDefaultOps) + + " default ones"); + return DstMIBuilder; } +Error GlobalISelEmitter::importDefaultOperandRenderers( + BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const { + for (const auto *DefaultOp : DefaultOps->args()) { + // Look through ValueType operators. + if (const DagInit *DefaultDagOp = dyn_cast<DagInit>(DefaultOp)) { + if (const DefInit *DefaultDagOperator = + dyn_cast<DefInit>(DefaultDagOp->getOperator())) { + if (DefaultDagOperator->getDef()->isSubClassOf("ValueType")) + DefaultOp = DefaultDagOp->getArg(0); + } + } + + if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) { + DstMIBuilder.addRenderer<AddRegisterRenderer>(DefaultDefOp->getDef()); + continue; + } + + if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) { + DstMIBuilder.addRenderer<ImmRenderer>(DefaultIntOp->getValue()); + continue; + } + + return failedImport("Could not add default op"); + } + + return Error::success(); +} + Error GlobalISelEmitter::importImplicitDefRenderers( BuildMIAction &DstMIBuilder, const std::vector<Record *> &ImplicitDefs) const { |