Note: This is a continuation of [RFC] TableGen support for RegisterBankInfo - Code Generation / Common CodeGen Infrastructure - LLVM Discussion Forums.
Proposal
This RFC tries to provide a way to define register bank mapping rules by matching TypedOperands, with generating time checks.
Following tablegen classes are introduced:
class RegBankTypeMapping<RegisterBank bank, TypedOperand type> {
RegisterBank Bank = bank;
TypedOperand Type = type;
}
class RegBankMappingRule<list<RegBankTypeMapping> typeMappings,
int cost = 1, int priority = 0, code predicate = [{}]> {
list<RegBankTypeMapping> TypeMappings = typeMappings;
int Priority = priority;
MappingID ID = DefaultMappingID;
int Cost = cost;
code Predicate = predicate;
// TODO: support alternative mapping
// bit IsAlternative = false;
}
class RegBankInstrMapping<list<GenericInstruction> opcodes,
list<RegBankMappingRule> rules> {
assert !not(!empty(opcodes)), "no opcodes";
assert !not(!empty(rules)), "no rules";
list<GenericInstruction> Opcodes = opcodes;
list<RegBankMappingRule> Rules = rules;
}
A sample mapping rule:
def : RegBankInstrMapping<[G_ADD], [
RegBankMappingRule<[RegBankTypeMapping<FPRRegBank, type0>],
predicate=[{Type0.isVector()}]>,
RegBankMappingRule<[RegBankTypeMapping<GPRRegBank, type0>]>
]>;
Fields explaination
RegBankTypeMapping
Type: The operand to match.Bank: This bank will be assigned to operandType.
RegBankInstrMapping
Opcodes: Define mapping rules for theseGenericInstructions, these instructions must have the same shape, i.e. after concatenatingOutOperandListandInOperandList, all instructions must contain the same kind ofTypedOperands, and these operands should be located in the same index.Rules: Mapping rules apply toOpcodes.
RegBankMappingRule
TypeMappings: Register bank assignments forTypedOperands, theTypeMappingsmust cover allTypedOperands in instruction operand list, otherwise, tablegen will issue an error.Priority: Mapping priority, the mapping rule with bigger priority value will appear before rules with smaller priority value in matching function.ID: The instruction mapping ID, which will be passed intoRegisterBankInfo::getInstructionMapping.Cost: Mapping cost, which will be passed intoRegisterBankInfo::getInstructionMapping.Predicate: When using predicates, the following identifiers are available:LLT [P]Type<N>;which is corresponded to operands in{In,Out}OperandList, i.e.[p]type<N> : TypedOperand.Register <opname>;which is the representative dag operand name in{In,Out}OperandList, i.e. ifTypedOperandistype0then it is the first dag operand name with recordtype0.
TableGen output
TableGen backend will generate a big value mapping table GeneratedOperandsMappings that covers all instruction shapes and register banks combinations from td file, a helper method
const InstructionMapping& getGeneratedInstructionMapping(const MachineInstr &MI) const;
will make decision by RegBankMappingRule and LLT size for current MI, if it can’t find a proper mapping, it will return a invalid mapping.
Limitations
- Mappings with break downs are not supported.
- Only
GenericInstructions without varargs are supported. - Per operand bank mapping is not supported, although it is possible, this would make the size of value mapping table very big .
- Alternative mappings are not involved here.
HwModeis not considered.