llvm.org GIT mirror llvm / b021f78
[TableGen] New default operand "undef_tied_input" This is a new special identifier which you can use as a default in OperandWithDefaultOps. The idea is that you use it for an input operand of an instruction that's tied to an output operand, and its semantics are that (in the default case) the input operand's value is not used at all. The detailed effect is that when instruction selection emits the instruction in the form of a pre-regalloc MachineInstr, it creates an IMPLICIT_DEF node to use as that input. If you're creating an MCInst with explicit register names, then the right handling would be to set the input operand to the same register as the output one (honouring the tie) and to add the 'undef' flag indicating that that register is deemed to acquire a new don't-care definition just before we read it. But I haven't done that in this commit, because there was no need to - no Tablegen backend seems to autogenerate default fields in an MCInst. Patch by: Simon Tatham Differential Revision: https://reviews.llvm.org/D60696 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362064 91177308-0d34-0410-b5e6-96231b3b80d8 Sjoerd Meijer 2 months ago
3 changed file(s) with 37 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
21312131
21322132 if (R->getName() == "node" || R->getName() == "srcvalue" ||
21332133 R->getName() == "zero_reg" || R->getName() == "immAllOnesV" ||
2134 R->getName() == "immAllZerosV") {
2134 R->getName() == "immAllZerosV" || R->getName() == "undef_tied_input") {
21352135 // Placeholder.
21362136 return TypeSetByHwMode(); // Unknown.
21372137 }
690690 return;
691691 }
692692
693 if (Def->getName() == "undef_tied_input") {
694 std::array ResultVTs = { N->getSimpleType(0) };
695 std::array InstOps;
696 auto IDOperandNo = NextRecordedOperandNo++;
697 AddMatcher(new EmitNodeMatcher("TargetOpcode::IMPLICIT_DEF",
698 ResultVTs, InstOps, false, false, false,
699 false, -1, IDOperandNo));
700 ResultOps.push_back(IDOperandNo);
701 return;
702 }
703
693704 // Handle a reference to a register class. This is used
694705 // in COPY_TO_SUBREG instructions.
695706 if (Def->isSubClassOf("RegisterOperand"))
30363036 importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule,
30373037 BuildMIAction &DstMIBuilder,
30383038 TreePatternNode *DstChild);
3039 Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder,
3039 Error importDefaultOperandRenderers(action_iterator InsertPt, RuleMatcher &M,
3040 BuildMIAction &DstMIBuilder,
30403041 DagInit *DefaultOps) const;
30413042 Error
30423043 importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
37763777 // end up with too many rendered operands.
37773778 if (DstIOperand.Rec->isSubClassOf("OperandWithDefaultOps")) {
37783779 DagInit *DefaultOps = DstIOperand.Rec->getValueAsDag("DefaultOps");
3779 if (auto Error = importDefaultOperandRenderers(DstMIBuilder, DefaultOps))
3780 if (auto Error = importDefaultOperandRenderers(
3781 InsertPt, M, DstMIBuilder, DefaultOps))
37803782 return std::move(Error);
37813783 ++NumDefaultOps;
37823784 continue;
38013803 }
38023804
38033805 Error GlobalISelEmitter::importDefaultOperandRenderers(
3804 BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const {
3806 action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
3807 DagInit *DefaultOps) const {
38053808 for (const auto *DefaultOp : DefaultOps->getArgs()) {
3809 Optional OpTyOrNone = None;
3810
38063811 // Look through ValueType operators.
38073812 if (const DagInit *DefaultDagOp = dyn_cast(DefaultOp)) {
38083813 if (const DefInit *DefaultDagOperator =
38093814 dyn_cast(DefaultDagOp->getOperator())) {
38103815 if (DefaultDagOperator->getDef()->isSubClassOf("ValueType"))
3816 OpTyOrNone = MVTToLLT(getValueType(
3817 DefaultDagOperator->getDef()));
38113818 DefaultOp = DefaultDagOp->getArg(0);
38123819 }
38133820 }
38143821
38153822 if (const DefInit *DefaultDefOp = dyn_cast(DefaultOp)) {
3816 DstMIBuilder.addRenderer(DefaultDefOp->getDef());
3823 auto Def = DefaultDefOp->getDef();
3824 if (Def->getName() == "undef_tied_input") {
3825 unsigned TempRegID = M.allocateTempRegID();
3826 M.insertAction(
3827 InsertPt, OpTyOrNone.getValue(), TempRegID);
3828 InsertPt = M.insertAction(
3829 InsertPt, M.allocateOutputInsnID(),
3830 &Target.getInstruction(RK.getDef("IMPLICIT_DEF")));
3831 BuildMIAction &IDMIBuilder = *static_cast(
3832 InsertPt->get());
3833 IDMIBuilder.addRenderer(TempRegID);
3834 DstMIBuilder.addRenderer(TempRegID);
3835 } else {
3836 DstMIBuilder.addRenderer(Def);
3837 }
38173838 continue;
38183839 }
38193840