[LLVMdev] Asserts in bundleWithPred() and bundleWithSucc()

Sergei Larin slarin at codeaurora.org
Mon Feb 4 08:59:35 PST 2013


Jakob,

> The intention was to identify code that may have been converted from
> the old style a little too quickly. I wanted to avoid bugs from a
> global s/setIsInsideBundle/bundleWithPred/g search and replace.

  This is a good intent. Maybe a bit temporal but sound nevertheless.

> finalizeBundle is calling 'MIBundleBuilder Bundle(MBB, FirstMI,
> LastMI)' which ought to work with pre-bundled instructions.

Not exactly.  Let me illustrate couple cases here (for illustration purposes
"^" means "isBundledWithPred()" and "v" means "isBundledWithSucc()"):

I have the following (existing) bundle for which I want to regenerate the
bundle header (You see that %R17 is not currently in the def list for the
bundle header).


  v  BUNDLE %P3<imp-def>, %R29<imp-use>, %D8<imp-use,kill>,
%D9<imp-use,kill>, %R6<imp-use>
*^v  STrid_indexed %R29, 80, %D8<kill>; mem:ST8[FixedStack2]
*^v  STrid_indexed %R29, 72, %D9<kill>; mem:ST8[FixedStack3]
*^v  %P3<def> = CMPEQri %R6, 0
*^   %R17<def> = TFR_cdnNotPt %P3<internal>, %R1
  v  BUNDLE %R29<imp-use>, %D10<imp-use,kill>, %R7<imp-use>, %D6<imp-use>
(next bundle).

finalizeBundle() is called with:

FirstMI == STrid_indexed %R29, 80, %D8<kill>; mem:ST8[FixedStack2]
LastMI == BUNDLE %R29<imp-use>, %D10<imp-use,kill>, %R7<imp-use>,
%D6<imp-use>

>From here this assert is triggered:

void MachineInstr::bundleWithSucc() {
  assert(!isBundledWithSucc() && "MI is already bundled with its
successor"); <<<<<<<<<<<<<<<<<<<<<<<<
  setFlag(BundledSucc);
  MachineBasicBlock::instr_iterator Succ = this;
  ++Succ;
  assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags");
  Succ->setFlag(BundledPred);
}


Here is the call stack:

#3  ... in llvm::MachineInstr::bundleWithSucc (this=0x4c6aa20) at
...lib/CodeGen/MachineInstr.cpp:882
#4  ... in llvm::MIBundleBuilder::insert (this=0x7fffffff7dc0, I=...,
MI=0x4c6aa20) at ...include/llvm/CodeGen/MachineInstrBuilder.h:417
#5  ... in llvm::MIBundleBuilder::prepend (this=0x7fffffff7dc0,
MI=0x4c6aa20) at ...include/llvm/CodeGen/MachineInstrBuilder.h:435
#6  ... in llvm::finalizeBundle (MBB=..., FirstMI=..., LastMI=...) at
...lib/CodeGen/MachineInstrBundle.cpp:112



  Let me give you another example though. I have the following existing
bundle:

    v  BUNDLE %R0<imp-def,dead>, %PC<imp-def>, %R18<imp-use>
  *^v  %R0<def> = AND_ri %R18, 128
  *^   JMP_EQriPnt_nv_V4 %R0<kill,internal>, 0, <BB#2>, %PC<imp-def>

I need to move an instruction into this bundle from another location and
insert it _between_ AND_ri and JMP_EQriPnt_nv_V4. I use MBB->splice(...) to
do that. Let's pretend that moved instruction was not bundled. New
instruction is pointed to by MachineBasicBlock::instr_iterator MII. New
bundle right after splice is:

    v  BUNDLE %R0<imp-def,dead>, %PC<imp-def>, %R18<imp-use>
  *^v  %R0<def> = AND_ri %R18, 128
  *    %R3<def> = HexagonEXTRACTU_ri_Inst %R18, 4, 3  <<<<<<<<<<<<<<<<<<<
MII
  *^   JMP_EQriPnt_nv_V4 %R0<kill,internal>, 0, <BB#2>, %PC<imp-def>

Now I have to integrate MII into the new bundle. As I do this:

MII->bundleWithPred();

I run into this assert:

void MachineInstr::bundleWithPred() {
  assert(!isBundledWithPred() && "MI is already bundled with its
predecessor");
  setFlag(BundledPred);
  MachineBasicBlock::instr_iterator Pred = this;
  --Pred;
  assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags");
<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  Pred->setFlag(BundledSucc);
}


Now think about what I need to do for all possible cases when original
instruction was previously bundled and that bundle also needs updating....
and on top of that almost every time I call bundleWith*() I have to guard it
with the check for isBundledWith*(). The code looks rather ugly at that
point...

...and if I start dissolve and reconstruct bundles every time I need to
manipulate them, I think original intent becomes a bit overly
constraining... 

Sergei




---
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by
The Linux Foundation


> -----Original Message-----
> From: Jakob Stoklund Olesen [mailto:stoklund at 2pi.dk]
> Sent: Friday, February 01, 2013 6:15 PM
> To: Sergei Larin
> Cc: llvmdev at cs.uiuc.edu
> Subject: Re: Asserts in bundleWithPred() and bundleWithSucc()
> 
> 
> On Feb 1, 2013, at 3:43 PM, "Sergei Larin" <slarin at codeaurora.org>
> wrote:
> 
> > I have a question about the following (four) asserts recently added
> in
> > bundleWithPred() and bundleWithSucc() (see below). What is the real
> > danger of reasserting a connection even if it already exist?
> 
> The intention was to identify code that may have been converted from
> the old style a little too quickly. I wanted to avoid bugs from a
> global s/setIsInsideBundle/bundleWithPred/g search and replace.
> 
> > My problem with them
> > happens when I try to call finalizeBundle() on an existing bundle to
> > which I have added a new instruction. The goal - a new bundle header
> > with liveness abbreviation, but because of these asserts I now have
> to
> > unbundle all, and re-bundle them right back again for no obvious
> benefit...
> 
> finalizeBundle is calling 'MIBundleBuilder Bundle(MBB, FirstMI,
> LastMI)' which ought to work with pre-bundled instructions. FirstMI and
> LastMI must be pointing at bundle boundaries, but you shouldn't need to
> unbundle everything.
> 
> Which iterators are you passing to finalizeBundle?
> 
> /jakob





More information about the llvm-dev mailing list