Changeset View
Standalone View
llvm/lib/MC/MCInstPrinter.cpp
Show First 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | if (!Annot.empty()) { | ||||
} else | } else | ||||
OS << " " << MAI.getCommentString() << " " << Annot; | OS << " " << MAI.getCommentString() << " " << Annot; | ||||
} | } | ||||
} | } | ||||
static bool matchAliasCondition(const MCInst &MI, const MCSubtargetInfo *STI, | static bool matchAliasCondition(const MCInst &MI, const MCSubtargetInfo *STI, | ||||
const MCRegisterInfo &MRI, unsigned &OpIdx, | const MCRegisterInfo &MRI, unsigned &OpIdx, | ||||
const AliasMatchingData &M, | const AliasMatchingData &M, | ||||
const AliasPatternCond &C) { | const AliasPatternCond &C, | ||||
bool &OrPredicateResult) { | |||||
// Feature tests are special, they don't consume operands. | // Feature tests are special, they don't consume operands. | ||||
if (C.Kind == AliasPatternCond::K_Feature) | if (C.Kind == AliasPatternCond::K_Feature) | ||||
return STI->getFeatureBits().test(C.Value); | return STI->getFeatureBits().test(C.Value); | ||||
if (C.Kind == AliasPatternCond::K_NegFeature) | if (C.Kind == AliasPatternCond::K_NegFeature) | ||||
return !STI->getFeatureBits().test(C.Value); | return !STI->getFeatureBits().test(C.Value); | ||||
// For feature tests where just one feature is required in a list, set the | |||||
// predicate result bit to whether the expression will return true, and only | |||||
// return the real result at the end of list marker. | |||||
if (C.Kind == AliasPatternCond::K_OrFeature) { | |||||
OrPredicateResult |= STI->getFeatureBits().test(C.Value); | |||||
return true; | |||||
} | |||||
if (C.Kind == AliasPatternCond::K_OrNegFeature) { | |||||
OrPredicateResult |= !(STI->getFeatureBits().test(C.Value)); | |||||
return true; | |||||
} | |||||
if (C.Kind == AliasPatternCond::K_EndOrFeatures) { | |||||
bool Res = OrPredicateResult; | |||||
OrPredicateResult = false; | |||||
return Res; | |||||
} | |||||
// Get and consume an operand. | // Get and consume an operand. | ||||
const MCOperand &Opnd = MI.getOperand(OpIdx); | const MCOperand &Opnd = MI.getOperand(OpIdx); | ||||
++OpIdx; | ++OpIdx; | ||||
// Check the specific condition for the operand. | // Check the specific condition for the operand. | ||||
switch (C.Kind) { | switch (C.Kind) { | ||||
case AliasPatternCond::K_Imm: | case AliasPatternCond::K_Imm: | ||||
Show All 11 Lines | static bool matchAliasCondition(const MCInst &MI, const MCSubtargetInfo *STI, | ||||
case AliasPatternCond::K_Custom: | case AliasPatternCond::K_Custom: | ||||
// Operand must match some custom criteria. | // Operand must match some custom criteria. | ||||
return M.ValidateMCOperand(Opnd, *STI, C.Value); | return M.ValidateMCOperand(Opnd, *STI, C.Value); | ||||
case AliasPatternCond::K_Ignore: | case AliasPatternCond::K_Ignore: | ||||
// Operand can be anything. | // Operand can be anything. | ||||
return true; | return true; | ||||
case AliasPatternCond::K_Feature: | case AliasPatternCond::K_Feature: | ||||
case AliasPatternCond::K_NegFeature: | case AliasPatternCond::K_NegFeature: | ||||
case AliasPatternCond::K_OrFeature: | |||||
case AliasPatternCond::K_OrNegFeature: | |||||
case AliasPatternCond::K_EndOrFeatures: | |||||
llvm_unreachable("handled earlier"); | llvm_unreachable("handled earlier"); | ||||
} | } | ||||
llvm_unreachable("invalid kind"); | llvm_unreachable("invalid kind"); | ||||
} | } | ||||
const char *MCInstPrinter::matchAliasPatterns(const MCInst *MI, | const char *MCInstPrinter::matchAliasPatterns(const MCInst *MI, | ||||
const MCSubtargetInfo *STI, | const MCSubtargetInfo *STI, | ||||
const AliasMatchingData &M) { | const AliasMatchingData &M) { | ||||
Show All 14 Lines | for (const AliasPattern &P : Patterns) { | ||||
// Check operand count first. | // Check operand count first. | ||||
if (MI->getNumOperands() != P.NumOperands) | if (MI->getNumOperands() != P.NumOperands) | ||||
return nullptr; | return nullptr; | ||||
// Test all conditions for this pattern. | // Test all conditions for this pattern. | ||||
ArrayRef<AliasPatternCond> Conds = | ArrayRef<AliasPatternCond> Conds = | ||||
M.PatternConds.slice(P.AliasCondStart, P.NumConds); | M.PatternConds.slice(P.AliasCondStart, P.NumConds); | ||||
unsigned OpIdx = 0; | unsigned OpIdx = 0; | ||||
bool OrPredicateResult = false; | |||||
if (llvm::all_of(Conds, [&](const AliasPatternCond &C) { | if (llvm::all_of(Conds, [&](const AliasPatternCond &C) { | ||||
lewis-revill: I don't know this code well enough to know if this is feasible but could this work by instead… | |||||
It's not possible to do this in this case, since the tests here are made up of more than one predicate, you end up with a list of things which must all be true, but with some with this or case in the middle. As an example of the set of predicates that make it here (taken from RISCVGenAsmWriter.inc // (GORCI GPR:$rd, GPR:$rs, { 1, 1, 1, 1, 0 }) - 327 {AliasPatternCond::K_RegClass, RISCV::GPRRegClassID}, {AliasPatternCond::K_RegClass, RISCV::GPRRegClassID}, {AliasPatternCond::K_Imm, uint32_t(30)}, {AliasPatternCond::K_OrFeature, RISCV::FeatureExtZbb}, {AliasPatternCond::K_OrFeature, RISCV::FeatureExtZbp}, {AliasPatternCond::K_EndOrFeatures, 0}, {AliasPatternCond::K_NegFeature, RISCV::Feature64Bit}, So in this case we only want to use this Asm string if the types match (the first three lines), and we have Zbb or Zbp in addition to not being 64-bit. Because of this I can't switch to using any_of because I'll match the wrong things. Adding the or features with the end of list marker meant I could keep this pattern and do a less invasive change. I suspect doing anything more complex might require a more in-depth change, I'm not sure if anyone who knows this part of the compiler might have other thoughts? simoncook: It's not possible to do this in this case, since the tests here are made up of more than one… | |||||
return matchAliasCondition(*MI, STI, MRI, OpIdx, M, C); | return matchAliasCondition(*MI, STI, MRI, OpIdx, M, C, | ||||
OrPredicateResult); | |||||
})) { | })) { | ||||
// If all conditions matched, use this asm string. | // If all conditions matched, use this asm string. | ||||
AsmStrOffset = P.AsmStrOffset; | AsmStrOffset = P.AsmStrOffset; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
// If no alias matched, don't print an alias. | // If no alias matched, don't print an alias. | ||||
▲ Show 20 Lines • Show All 73 Lines • Show Last 20 Lines |
I don't know this code well enough to know if this is feasible but could this work by instead checking at this point if the pattern is an 'or' pattern, and selecting using 'any_of' if that's the case? We could then avoid adding the K_Or conditions.