[llvm-commits] Trampoline support (pointers nested funtions)

Evan Cheng evan.cheng at apple.com
Tue Jul 31 15:08:00 PDT 2007


On Jul 27, 2007, at 3:38 AM, Duncan Sands wrote:

> Hi Evan,
>
>> Some nit picks.
>>
>> 1. Please don't use "Chain" for stand for function static chain. It
>> confuses backend guys like me. :-) "Chain" stands for control flow
>> dependency in the backend.
>
> I've replaced Chain with Nest everywhere, eg the attribute is now  
> 'nest'.

Thanks.

>
>
>> 2. Purely a stylistic thing:
>>
>> +SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
>> +                                             SelectionDAG &DAG) {
>> +  SDOperand Root = Op.getOperand(0);
>> +  SDOperand Trmp = Op.getOperand(1); // trampoline
>> +  SDOperand FPtr = Op.getOperand(2); // nested function
>> +  SDOperand SChn = Op.getOperand(3); // static chain
>> +
>> +  SrcValueSDNode *TrmpSV = cast<SrcValueSDNode>(Op.getOperand(4));
>> +
>> +  if (Subtarget->is64Bit()) {
>> +    return SDOperand(); // not yet supported
>> +  } else {
>>
>> If you move the check is64Bit() to the beginning of function, there
>> is no need to nest the part that actually do the work in the "else"
>> clause.
>
> I'd prefer to leave it as it is: this is where the code for 64 bit
> support will go, once added.  And since right now codegen will abort
> on trampoline lowering on x86-64, I don't think it matters if a few
> cycles are wasted before the abort :)  By the way, I think aborting
> is the right thing to do: if someone is creating a trampoline, most
> likely they are going to use it, i.e. jump to the code it contains.
> If we lower trampoline initialization to nothing on architectures that
> don't yet support it, then the code will appear to compile fine but  
> will
> die very horribly at runtime, by jumping to a bunch of random bytes...
>

Ok. It's just a nit pick.

>> 3. In X86TargetLowering::LowerTRAMPOLINE():
>> +    case CallingConv::X86_StdCall: {
>> +      Move = 0xb9; // Pass chain in ECX
>>
>> I assume this is the ModR/M byte?
>
> Well, it's MOV32ri.

Then it should be 0xb8?

>
>
>> Can you refactor ModRMByte() from X86CodeEmitter.cpp (probably also  
>> getX86RegNum)
>> and use that to calculate this instead?
>
> For the reasons explained in the next paragraph, I've taken a  
> minimal approach.
> (1) I've introduced X86CodeEmitter.h, which contains native X86  
> Register numbers
> factored out of X86CodeEmitter.cpp.

Please factor out getX86RegNum() as well. Perhaps put them in  
X86RegisterInfo.cpp (since lowering really shouldn't depend on  
codeemitter...) Do getX86RegNum(X86::EAX) rather than make use  
N86::EAX directly.

>
> (2) In LowerTRAMPOLINE, names like N86::ECX are used to name the  
> register used.
> (3) Rather than using 0xb8 and 0xE9, I've introduced symbolic names  
> MOV32ri
> and JMP.  I could also get these by doing something like this:
> const X86InstrInfo *TII =  
> ((X86TargetMachine&)getTargetMachine()).getInstrInfo();
> unsigned char MOV32ri = TII->getBaseOpcodeFor(&TII- 
> >get(X86::MOV32ri));
> But it didn't seem worth it (is there a way to extract the machine  
> opcode
> statically?).

Please go through X86InstrInfo to get the opcode numbers instead of  
hard coding it.

>
>
>> Also, isn't the static chain register described in X86CallingConv.td?
>
> It is, but it's hard to use here.  The problem is that when lowering  
> the
> init.trampoline intrinsic you only have a pointer to the target  
> function.
> From this pointer you would like to find out which register a certain
> parameter will be passed in for that function.  Not so easy!  It's  
> like
> having a call instruction without having the arguments.  In order to
> exploit X86CallingConv.td, you have to use all the lowering machinery,
> which isn't adapted to this case.  For example, you could try to  
> synthesize
> a fake call.  Or you could pretend to be lowering the target  
> function.  I
> tried it, and it can be done with a lot of horrible hacking.  But  
> it's not
> worth it.  It's much simpler to simply grab the calling convention  
> and use
> that, which unfortunately means keeping LowerTRAMPOLINE and
> X86CallingConv.td in sync.  Personally I can live with that,  
> especially since
> I've seen the alternative and it still wakes me up screaming at  
> night :)
> But maybe you can see a reasonable way of doing it?

Seems like a deficiency in CCState class. Chris, your thoughts?

Evan

>
>
> Since I need to map the calling convention to a native X86 register  
> number,
> I chose to bypass X86::ECX etc and directly use N86::ECX.  This  
> would be
> different if the register number was being extracted from lowering +
> CCInfo.
>
>> Magic number is confusing. :-)
>
> Hopefully it's more readable now.  The amount of code factorization is
> minimal which is a pity but seems the best choice.
>
>> Looks great otherwise. Thanks!
>
> Thanks for reviewing!
>
> Duncan.
> <tramp.diff><tramp-gcc.diff>




More information about the llvm-commits mailing list