[LLVMdev] Overlapping register classes

Jakob Stoklund Olesen stoklund at 2pi.dk
Tue Mar 17 23:59:31 PDT 2009


Jakob Stoklund Olesen <stoklund at 2pi.dk> writes:

> The Blackfin 32-bit registers divide naturally into several classes. I
> have modelled these register classes without knowing anything about what
> the code generator expects.

Here is what I have done for now: I have added a narrowing move
instruction for each register subclass, much like the X86 MOV32to32_
instruction:

def MOVE_d: F1<(outs D:$dst), (ins ALL:$src),"$dst = $src;", []>;
def MOVE_p: F1<(outs P:$dst), (ins ALL:$src),"$dst = $src;", []>;

I do not use these move instructions in patterns; that would be too
messy.  Instead, I insert narrowing moves in the selection DAG after
instruction selection is complete, before scheduling.  Since the
narrowing moves take operands from the ALL regclass, ScheduleDAGSDNodes
gets upset unless you apply the following patch:

--- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
@@ -262,7 +262,7 @@ void ScheduleDAGSDNodes::AddOperand(MachineInstr *MI, SDValue Op,
       const TargetRegisterClass *RC= getInstrOperandRegClass(TRI, *II, IIOpNum);
       assert((RC || II->isVariadic()) && "Expected reg class info!");
       const TargetRegisterClass *VRC = MRI.getRegClass(VReg);
-      if (RC && VRC != RC) {
+      if (RC && VRC != RC && !VRC->hasSuperClass(RC)) {
         cerr << "Register class of operand and regclass of use don't agree!\n";
         cerr << "Operand = " << IIOpNum << "\n";
         cerr << "Op->Val = "; Op.getNode()->dump(DAG); cerr << "\n";

When running llc with -join-cross-class-copies as Evan suggested, it
produces good results.

I am going to move on to implementing advanced features like jumps and
condition codes now :-)

Thanks,
/jakob





More information about the llvm-dev mailing list