[LLVMdev] Two labels around one instruction in Codegen

Duncan Sands
Tue, 06 Nov 2007 09:33:56 -0000

Hi Nicolas,

> In order to have exceptions for non-call instructions (such as sdiv,
> load or stores), I'm modifying codegen so that it generates a
BeginLabel
> and an EndLabel between the "may throwing" instruction. This is
what the
> codegen of an InvokeInst does.

the rule is that all instructions between eh begin labelN and eh end labelN
must unwind to the same landing pad.  This is why invokes are bracketed by
such labels.  There are also two other cases to consider: (1) potentially
throwing instructions which are not allowed to throw (nounwind), (2) throwing
instructions for which any thrown exception will not be processed in this
function.  In case (1) the instruction should have no entry in the final
dwarf exception table, while in case (2) it should have an entry.  We don't
handle (1) right now, however the plan is that nounwind calls will also be
bracketed by labels but will have no associated landing pad.  As for (2),
the dwarf writer scans all instructions in the function and if it sees a
call that is not bracketed by labels then it generates an appropriate entry
in the exception table (this will of course need to be modified to consider
all throwing instructions - note that this means that "maythrow"
markings will
have to exist right to the end of code generation!); it is done this way
because labels inhibit optimizations (we used to bracket all calls with
labels, but stopped doing that because of the optimization problem).  I'm
mentioning this because the begin and end labels are not *between* maythrow
instructions, they bracket them.

> However, when generating native code, only BeginLabel is generated, and
> it is generated after the instruction. I'm not familiar with DAGs in
the
> codegen library, so here are my 2-cents thoughts why:
>
> 1) BeginLabel and EndLabel are generated with:
>   DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
>                             DAG.getConstant({Begin|End}Label, MVT::i32)));
>
> This seems to work with InvokeInst instructions, because the root of the
> DAG is modified by the instruction. With instructions such as sdiv, the
> root is not modified: the instruction only lowers itself to:
> DAG.getNode(OpCode, Op1.getValueType(), Op1, Op2)

I think that not creating a new root means that the instruction is allowed
to be re-ordered with respect to other instructions, as long as it occurs
before its uses.  Re-ordering is rather dubious for instructions that may
throw, though it's not clear what is acceptable.  I think you probably need
a new selection DAG "throw" node which you wrap throwing instructions
in, a
bit like a TokenFactor.  This throw node would be setup in such a way as to
be bracketable by labels.

> Which probably makes the codegen think EndLabel and BeginLabel are in
> the same place

In that case I would expect them both to be deleted...

> 2) Since there is no ordering between the node for the sdiv instruction
> and the labels, the sdiv instruction can be generated anywhere.
>
> These assumptions may be wrong, but it's the best I could come up with
;-).
>
> If someone could correct me and help me found how to correctly generate
> two labels between one instruction, that would be great! :)

Ciao,

Duncan.