Using patterns inside patterns

Is there currently a way to use a pattern inside of another pattern?

Micah Villmow

Systems Engineer

Advanced Technology & Performance

Advanced Micro Devices Inc.

4555 Great America Pkwy,

Santa Clara, CA. 95054

P: 408-572-6219

F: 408-572-6596



I am working on a LLVM backend for a new platform. The target has a virtual instruction set and unlimited virtual registers. After going through LLVM documentation and source code, it looks like there are two possible ways to implement it with LLVM:



1) Method #1: follow common code generator path (TableGen, LLVMTargetMachine, etc), similarly as the Sparc and x86 targets. Since the target has unlimited number of virtual registers, register allocation is no use here. I can skip the register allocation by overloading the register allocator with one does no allocation. Is there any assumption in this infrastructure that would prevent from doing so?



2) Method #2: follow the custom code generator path, similar as the CBackend and MSIL targets.







I’d like to evaluate which method is more appropriate for this particular target. Method#1 provides some optimizations at machine instruction level (in this case, the virtual instruction set). Is the custom path capable of doing the same?







Thanks,



-Sanjay

|

Sanjay, I am working on backend with similar constraints using Method #1. You can use createVirtualRegister for all your register allocation needs. The only issue is that it currently resets the virtual register count at the beginning of each function call. Look at the thread, “Virtual Register allocation across functions” to see possible solutions for this issue.

I am not sure what you are looking to do. Please provide a mark up example.

Evan

I do not have access to a subtraction routine, as it is considered add
with negation on the second parameter, so I have this pattern:

// integer subtraction

// a - b ==> a + (-b)

def ISUB : Pat<(sub GPRI32:$src0, GPRI32:$src1),

               (IADD GPRI32:$src0, (INEGATE GPRI32:$src1))>;

I am attemping to do 64 bit integer shifts and using the following
pattern:

def LSHL : Pat<(shl GPRI64:$src0, GPRI32:$src1),

        (LCREATE (ISHL (LLO GPRI64:$src0), GPRI32:$src1),

         (IOR (ISHL (LHI GPRI64:$src0), GPRI32:$src1), (IOR (USHR (LLO
GPRI64:$src0), (IADD (LOADCONST_i32 32), (INEGATE GPRI32:$src1))), (USHR
(LLO GPRI64:$src0), (IADD GPRI32:$src1, (LOADCONST_i32 -32))))))>;

However, I have two adds that I could map to subtractions, what I would
like to be able to do is:

def LSHL : Pat<(shl GPRI64:$src0, GPRI32:$src1),

        (LCREATE (ISHL (LLO GPRI64:$src0), GPRI32:$src1),

         (IOR (ISHL (LHI GPRI64:$src0), GPRI32:$src1), (IOR (USHR (LLO
GPRI64:$src0), (ISUB (LOADCONST_i32 32), GPRI32:$src1)), (USHR (LLO
GPRI64:$src0), (ISUB GPRI32:$src1, (LOADCONST_i32 32))))))>;

However my error is:

In LSHL: Unrecognized node 'ISUB'!

So, it obviously wants SDNodes and not Pat's, so is there a way I can
align this to get it so it will accept a Pat or to translate a Pat as an
SDNode?

Micah,

The best way to find answers to these types of questions is to look for examples in other targets. For example, PPC has this Pat pattern which synthesizes an immediate with two instructions:

// Arbitrary immediate support. Implement in terms of LIS/ORI.
def : Pat<(i32 imm:$imm),
(ORI (LIS (HI16 imm:$imm)), (LO16 imm:$imm))>;

It also has stuff like this:

// Implement the ‘not’ operation with the NOR instruction.
def NOT : Pat<(not GPRC:$in),
(NOR GPRC:$in, GPRC:$in)>;

For more information, please see the powerpc .td files. In answer to your question, you can’t map target-independent nodes to target-independent nodes, you have to map them to target specific instructions: ORI/LIS/NOR in these examples.

-Chris