diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -810,6 +810,12 @@ return hasProperty(MCID::Pseudo, Type); } + /// Return true if this instruction doesn't produce any output in the form of + /// executable instructions. + bool isMetaInstruction(QueryType Type = AnyInBundle) const { + return hasProperty(MCID::Meta, Type); + } + bool isReturn(QueryType Type = AnyInBundle) const { return hasProperty(MCID::Return, Type); } @@ -1306,30 +1312,6 @@ getOperand(0).getSubReg() == getOperand(1).getSubReg(); } - /// Return true if this instruction doesn't produce any output in the form of - /// executable instructions. - bool isMetaInstruction() const { - switch (getOpcode()) { - default: - return false; - case TargetOpcode::IMPLICIT_DEF: - case TargetOpcode::KILL: - case TargetOpcode::CFI_INSTRUCTION: - case TargetOpcode::EH_LABEL: - case TargetOpcode::GC_LABEL: - case TargetOpcode::DBG_VALUE: - case TargetOpcode::DBG_VALUE_LIST: - case TargetOpcode::DBG_INSTR_REF: - case TargetOpcode::DBG_PHI: - case TargetOpcode::DBG_LABEL: - case TargetOpcode::LIFETIME_START: - case TargetOpcode::LIFETIME_END: - case TargetOpcode::PSEUDO_PROBE: - case TargetOpcode::ARITH_FENCE: - return true; - } - } - /// Return true if this is a transient instruction that is either very likely /// to be eliminated during register allocation (such as copy-like /// instructions), or if this instruction doesn't have an execution-time cost. diff --git a/llvm/include/llvm/MC/MCInstrDesc.h b/llvm/include/llvm/MC/MCInstrDesc.h --- a/llvm/include/llvm/MC/MCInstrDesc.h +++ b/llvm/include/llvm/MC/MCInstrDesc.h @@ -149,6 +149,7 @@ Variadic, HasOptionalDef, Pseudo, + Meta, Return, EHScopeReturn, Call, @@ -264,6 +265,10 @@ /// correspond to a real machine instruction. bool isPseudo() const { return Flags & (1ULL << MCID::Pseudo); } + /// Return true if this is a meta instruction that doesn't + /// produce any output in the form of executable instructions. + bool isMetaInstruction() const { return Flags & (1ULL << MCID::Meta); } + /// Return true if the instruction is a return. bool isReturn() const { return Flags & (1ULL << MCID::Return); } diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -568,6 +568,9 @@ bit isPseudo = false; // Is this instruction a pseudo-instruction? // If so, won't have encoding information for // the [MC]CodeEmitter stuff. + bit isMeta = false; // Is this instruction a meta-instruction? + // If so, won't produce any output in the form of + // executable instructions bit isExtractSubreg = false; // Is this instruction a kind of extract subreg? // If so, make sure to override // TargetInstrInfo::getExtractSubregLikeInputs. @@ -1099,6 +1102,7 @@ let hasCtrlDep = true; let hasSideEffects = false; let isNotDuplicable = true; + let isMeta = true; } def EH_LABEL : StandardPseudoInstruction { let OutOperandList = (outs); @@ -1107,6 +1111,7 @@ let hasCtrlDep = true; let hasSideEffects = false; let isNotDuplicable = true; + let isMeta = true; } def GC_LABEL : StandardPseudoInstruction { let OutOperandList = (outs); @@ -1115,6 +1120,7 @@ let hasCtrlDep = true; let hasSideEffects = false; let isNotDuplicable = true; + let isMeta = true; } def ANNOTATION_LABEL : StandardPseudoInstruction { let OutOperandList = (outs); @@ -1129,6 +1135,7 @@ let InOperandList = (ins variable_ops); let AsmString = ""; let hasSideEffects = false; + let isMeta = true; } def EXTRACT_SUBREG : StandardPseudoInstruction { let OutOperandList = (outs unknown:$dst); @@ -1150,6 +1157,7 @@ let hasSideEffects = false; let isReMaterializable = true; let isAsCheapAsAMove = true; + let isMeta = true; } def SUBREG_TO_REG : StandardPseudoInstruction { let OutOperandList = (outs unknown:$dst); @@ -1169,30 +1177,35 @@ let InOperandList = (ins variable_ops); let AsmString = "DBG_VALUE"; let hasSideEffects = false; + let isMeta = true; } def DBG_VALUE_LIST : StandardPseudoInstruction { let OutOperandList = (outs); let InOperandList = (ins variable_ops); let AsmString = "DBG_VALUE_LIST"; let hasSideEffects = 0; + let isMeta = true; } def DBG_INSTR_REF : StandardPseudoInstruction { let OutOperandList = (outs); let InOperandList = (ins variable_ops); let AsmString = "DBG_INSTR_REF"; let hasSideEffects = false; + let isMeta = true; } def DBG_PHI : StandardPseudoInstruction { let OutOperandList = (outs); let InOperandList = (ins variable_ops); let AsmString = "DBG_PHI"; let hasSideEffects = 0; + let isMeta = true; } def DBG_LABEL : StandardPseudoInstruction { let OutOperandList = (outs); let InOperandList = (ins unknown:$label); let AsmString = "DBG_LABEL"; let hasSideEffects = false; + let isMeta = true; } def REG_SEQUENCE : StandardPseudoInstruction { let OutOperandList = (outs unknown:$dst); @@ -1220,18 +1233,21 @@ let InOperandList = (ins i32imm:$id); let AsmString = "LIFETIME_START"; let hasSideEffects = false; + let isMeta = true; } def LIFETIME_END : StandardPseudoInstruction { let OutOperandList = (outs); let InOperandList = (ins i32imm:$id); let AsmString = "LIFETIME_END"; let hasSideEffects = false; + let isMeta = true; } def PSEUDO_PROBE : StandardPseudoInstruction { let OutOperandList = (outs); let InOperandList = (ins i64imm:$guid, i64imm:$index, i8imm:$type, i32imm:$attr); let AsmString = "PSEUDO_PROBE"; let hasSideEffects = 1; + let isMeta = true; } def ARITH_FENCE : StandardPseudoInstruction { let OutOperandList = (outs unknown:$dst); @@ -1239,6 +1255,7 @@ let AsmString = ""; let hasSideEffects = false; let Constraints = "$src = $dst"; + let isMeta = true; } def STACKMAP : StandardPseudoInstruction { diff --git a/llvm/unittests/CodeGen/LexicalScopesTest.cpp b/llvm/unittests/CodeGen/LexicalScopesTest.cpp --- a/llvm/unittests/CodeGen/LexicalScopesTest.cpp +++ b/llvm/unittests/CodeGen/LexicalScopesTest.cpp @@ -69,6 +69,7 @@ memset(&DbgValueInst, 0, sizeof(DbgValueInst)); DbgValueInst.Opcode = TargetOpcode::DBG_VALUE; DbgValueInst.Size = 1; + DbgValueInst.Flags = 1U << MCID::Meta; // Boilerplate that creates a MachineFunction and associated blocks. MF = createMachineFunction(Ctx, Mod); diff --git a/llvm/utils/TableGen/CodeGenInstruction.h b/llvm/utils/TableGen/CodeGenInstruction.h --- a/llvm/utils/TableGen/CodeGenInstruction.h +++ b/llvm/utils/TableGen/CodeGenInstruction.h @@ -271,6 +271,7 @@ bool hasExtraDefRegAllocReq : 1; bool isCodeGenOnly : 1; bool isPseudo : 1; + bool isMeta : 1; bool isRegSequence : 1; bool isExtractSubreg : 1; bool isInsertSubreg : 1; diff --git a/llvm/utils/TableGen/CodeGenInstruction.cpp b/llvm/utils/TableGen/CodeGenInstruction.cpp --- a/llvm/utils/TableGen/CodeGenInstruction.cpp +++ b/llvm/utils/TableGen/CodeGenInstruction.cpp @@ -415,6 +415,7 @@ hasExtraDefRegAllocReq = R->getValueAsBit("hasExtraDefRegAllocReq"); isCodeGenOnly = R->getValueAsBit("isCodeGenOnly"); isPseudo = R->getValueAsBit("isPseudo"); + isMeta = R->getValueAsBit("isMeta"); ImplicitDefs = R->getValueAsListOfDefs("Defs"); ImplicitUses = R->getValueAsListOfDefs("Uses"); diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp --- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -943,6 +943,7 @@ // Emit all of the target independent flags... if (Inst.isPreISelOpcode) OS << "|(1ULL<