[Query] Programming Register Allocation

So I have a good understanding of what and how I want to do in the abstract sense. I am starting to gain a feel for the code base, and I see that I may have a allocator up and running much faster than I once thought thanks to the easy interfaces.

What I need to know is how to access the machine register classes. Also, I need to know which virtual register is to be mapped into each specific register class. I assume there is type information on the registers. I need to know how to access it. And a afterthought, does LLVM place casts into different virtual registers, or do I need to include casting of floats to integers or vice versa when I see ADD i32 float i32?

Thanks,
Jeff Kunkel

What I need to know is how to access the machine register classes. Also, I
need to know which virtual register is to be mapped into each specific
register class. I assume there is type information on the registers. I need
to know how to access it.

MachineRegisterInfo::getRegClass will give you the TargetRegisterClass for a
given virtual register. Each TargetRegisterClass has an "allocation order"
that enumerates all physical registers valid for that class.

And a afterthought, does LLVM place casts into
different virtual registers, or do I need to include casting of floats to
integers or vice versa when I see ADD i32 float i32?

The instruction selector creates all necessary conversion instructions.

Thanks for the information.

I still don’t know how do I partition registers into different classes from the virtual registers? For instance, I have the function who which iterates over the instructions, but I don’t know how to write the function which returns the different register class.

void RAOptimal::Gather(MachineFunction &Fn) {
// Gather just iterates over the blocks, basicblocks, ect. until
// it finds the MachineOperand. When it finds the operand, it
// checks to see if the operand is a register, if so, it parses
// the register to find which set it is suppose to be in.

// time is an artificial time used to denote whether an operand came
// before or after another operand.
unsigned time;
time = 0; // Initialize time.

// For each block:
for( MachineFunction::iterator mfi=Fn.begin(), mfe=Fn.end(); mfi != mfe; ++mfi ) {
// for each byte code line:
for( MachineBasicBlock::iterator mbbi = mfi->begin(), mbbe = mfi->end(); mbbi != mbbe; ++mbbi ) {
// for each variable used:
for( int opi=0, ope=mbbi->getNumOperands(); opi != ope; ++opi ) {
// Get the variable
const MachineOperand mop = mbbi->getOperand( opi );
// If it is a register, notify the class.
if( mop.isReg() ) {
// DEBUG( dbgs() << "Found the register " << mop );
if( mop.isDef() || mop.isUse() ) {
// The instruction has defined the register.
// Or, the instruction uses the register.
unsigned reg = mop.getReg();
unsigned set = who(Fn, mbbi, mop, reg);
RegisterSets[ set ].Notify( reg, time, mbbi );
// Increment time after each Notify to keep the reg’s times from
// overlapping.
++time;
} else {
assert( 0 && “The register is always defining or used.” );
}
}
}
}
}
}

Thanks,
Jeff Kunkel

I solve my own problem.

mbbi->getRegInfo()->getRegClass( reg )

will return the register class.

Thanks,
Jeff Kunkel