Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [omr-dev] When to generate TreeTops

Hi Dibyendu,

I am not an IL expert but I think I can explain what's happening in your example.

(small side question: perhaps part of the confusion here has to do with the, very unfortunate, dual meaning of the name "TreeTop"?)

The important rule to remember is that TreeTops define program order. With that in mind, it might be helpful to look at what IL is generated in either case. (Disclaimer: I'm going to make some educated guesses about what the IL looks like based on the code you've shown and the behaviour you've described. However, I can't guarantee that this is what you'll actually see in a log file.)

When the load is *not* under its own TreeTop, the generated IL will look something like:

```
istorei
  aladd
    aload "base"
    lconst 4
  iconst 42
ireturn
  iloadi
    aladd
      aload "base"
      lconst 4
```

Even though you create the load before the store, it gets "connected" to the `ireturn` node. So, the load is evaluated after the store (when the return is evaluated). However, when the load is anchored to a TreeTop, you get:

```
treetop
  iloadi <---------+
    aladd          |
      aload "base" |
      lconst 4     |
istorei            |
  aladd            |
    aload "base"   |
    lconst 4       |
  iconst 42        |
ireturn            |
  iloadi --------->+  (this is a commond node)
```

Here, the load is "connected" (inserted into the IL) before the store and will, therefore, be evaluated first.

So, to summarize, you use TreeTops to describe program order. You generate them when you need to force some evaluation order. (Disclaimer: I believe the optimizer can still reorder things if TreeTops have no side-effects but I am not very familiar with the details.)

I hope this is helpful :) ,

--
Leonardo

Sent from ProtonMail, Swiss-based encrypted email.

> I was wondering how to decide whether a TreeTop must be generated. In
> 
> the example below (this is in my wip C api but the operations should
> 
> be clear). Here the function takes an argument of type int32_t* and I
> 
> am trying to get/set the value at array offset 1.
> 
> static bool test2_il(JIT_ILInjectorRef ilinjector, void *userdata) {
> 
> JIT_CreateBlocks(ilinjector, 1);
> 
> JIT_SetCurrentBlock(ilinjector, 0);
> 
> auto index = JIT_ConstInt32(4); // Byte offset of int32_t[1]
> 
> auto base = JIT_LoadParameter(ilinjector, 0); // Load arg
> 
> auto value = JIT_ArrayLoad(ilinjector, base, index, JIT_Int32); //
> 
> Get arg[1]
> 
> JIT_GenerateTreeTop(ilinjector, value); // Without TreeTop here we
> 
> get the stored value below
> 
> JIT_ArrayStore(ilinjector, base, index, JIT_ConstInt32(42)); //
> 
> Set arg[1] = 42
> 
> auto node = JIT_CreateNode1C(OP_ireturn, value);
> 
> JIT_GenerateTreeTop(ilinjector, node);
> 
> JIT_CFGAddEdge(ilinjector,
> 
> JIT_BlockAsCFGNode(JIT_GetCurrentBlock(ilinjector)),
> 
> JIT_GetCFGEnd(ilinjector));
> 
> return true;
> 
> }
> 
> If I don't have the Load anchored in a TreeTop then the generated code
> 
> returns the value from the store - i.e. 42 instead of whatever was
> 
> originally at arg[1].
> 
> In general - what criteria should be used to decide whether to
> 
> generate TreeTop or not? (I have read the docs - I am looking for more
> 
> specific info).
> 
> Thanks and Regards
> 
> Dibyendu


Back to the top