So I tried adding a new register class to the x86 target: def WIDE32 : RegisterClass<"X86", [i32, f32], 32, (add GR32, FR32)>; I thought this would be a harmless thing to do since the new register class is not being referenced anywhere. I was wrong, it caused all kinds of assertion failures from tablegen's isel pattern generator. It appears that tablegen is inferring the 'type' of an individual register by enumerating all the register classes it appears in. Some things, like using implicit defs in SDNodes, only works for registers with a unique type. My WIDE32 class caused GR32 registers to no longer have a unique type, breaking the world. This seems too fragile to me. Besides my current experiments with wide register classes, Blackfin's general purpose registers can hold both i32 and v2i16 types. Does that mean Blackfin instructions can't use GPR implicit defs as SDNode results? I would like to fix this, but I am not sure how. I could: - Disable type inference for individual registers entirely, or - Add a ValueType field to the Register tablegen class, so types are not inferred by enumerating register classes. Any suggestions? /jakob
Jakob Stoklund Olesen <stoklund at 2pi.dk> writes:> It appears that tablegen is inferring the 'type' of an individual > register by enumerating all the register classes it appears in. Some > things, like using implicit defs in SDNodes, only works for registers > with a unique type. My WIDE32 class caused GR32 registers to no > longer have a unique type, breaking the world.I can't remeber the specific situation, but I remember running into this kind of problem before.> This seems too fragile to me.Yes, it is. :(> - Disable type inference for individual registers entirely, or > > - Add a ValueType field to the Register tablegen class, so types are > not inferred by enumerating register classes.I tend to think the second would be preferable, but how would we handle registers than can hold different types of values? -Dave
On Sep 23, 2011, at 1:38 PM, David A. Greene wrote:> Jakob Stoklund Olesen <stoklund at 2pi.dk> writes: > >> It appears that tablegen is inferring the 'type' of an individual >> register by enumerating all the register classes it appears in. Some >> things, like using implicit defs in SDNodes, only works for registers >> with a unique type. My WIDE32 class caused GR32 registers to no >> longer have a unique type, breaking the world. > > I can't remeber the specific situation, but I remember running into > this kind of problem before. > >> This seems too fragile to me. > > Yes, it is. :( > >> - Disable type inference for individual registers entirely, or >> >> - Add a ValueType field to the Register tablegen class, so types are >> not inferred by enumerating register classes. > > I tend to think the second would be preferable, but how would we handle > registers than can hold different types of values?AFAIK, the type inference is only a convenience, you can always use explicit casts to get at the other types. It's the use of HasOneImplicitDefWithKnownVT() that scares me, I don't think there is any workaround for that. /jakob /// HasOneImplicitDefWithKnownVT - If the instruction has at least one /// implicit def and it has a known VT, return the VT, otherwise return /// MVT::Other. MVT::SimpleValueType CodeGenInstruction:: HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const { if (ImplicitDefs.empty()) return MVT::Other; // Check to see if the first implicit def has a resolvable type. Record *FirstImplicitDef = ImplicitDefs[0]; assert(FirstImplicitDef->isSubClassOf("Register")); const std::vector<MVT::SimpleValueType> &RegVTs TargetInfo.getRegisterVTs(FirstImplicitDef); if (RegVTs.size() == 1) return RegVTs[0]; return MVT::Other; }
Reasonably Related Threads
- [LLVMdev] Registers and isel type inference
- [LLVMdev] Registers and isel type inference
- [LLVMdev] Registers and isel type inference
- Nested instruction patterns rejected by GlobalISel when having registers in Defs
- [LLVMdev] Types inference in tblgen: Multiple exceptions