DFAPacketizer assert failure

For some reason on my VLIW target DFAPacketizer fails at

assert(CachedTable.count(StateTrans) != 0);

in the following function:

// reserveResources - Reserve the resources occupied by a MCInstrDesc and
// change the current state to reflect that change.
void DFAPacketizer::reserveResources(const llvm::MCInstrDesc *MID) {
unsigned InsnClass = MID->getSchedClass();
const llvm::InstrStage *IS = InstrItins->beginStage(InsnClass);
unsigned FuncUnits = IS->getUnits();
UnsignPair StateTrans = UnsignPair(CurrentState, FuncUnits);
ReadTable(CurrentState);
assert(CachedTable.count(StateTrans) != 0);
CurrentState = CachedTable[StateTrans];
}

This happens at the packetization stage, i.e. scheduling seems to work. My schedule description is not very different from Hexagon or R600. I’m not quite sure why this is happening. Would someone be able to shed some light on this?

Any help is appreciated.

It's hard to make a guess based on that assertion alone. Apparently there is no transition in the DFA for these values.

Do the arguments (e.g. CurrentState and FuncUnits) look reasonable?

-Krzysztof

It's hard to make a guess based on that assertion alone. Apparently there
is no transition in the DFA for these values.

Do the arguments (e.g. CurrentState and FuncUnits) look reasonable?

FuncUnits = 0
CurrentState = 0
StateTrans = {first = 0, second = 0}

I understand that there is something wrong with the state machine but I
can't figure out what exactly. My scheduler description is the same as for
Hexagon or R600. So why would DFA would look any different for my target?
What could be the problem?

Does the instruction that is being added have an itinerary associated with it?

I'm not sure what you mean when you say that your scheduler description is the same as for Hexagon or R600. Those two are very different and whatever you have, it cannot be the same as both of them.

-Krzysztof

Does the instruction that is being added have an itinerary associated with
it?

You are right, I don't know how I missed it. It is the CFI instruction. I

don't remember giving it any itinerary.

I'm not sure what you mean when you say that your scheduler description is
the same as for Hexagon or R600. Those two are very different and whatever
you have, it cannot be the same as both of them.

Sorry for the confusion. I should have said that my description is similar

to Hexagon.

Thanks for the help,

R

How come scheduling worked without giving a description to the CFI instruction but packetization failed?

R

Does the instruction that is being added have an itinerary associated with
it?

So I checked again, and it turns out that it does have an itinerary
associated with it. However it is a pseudo instruction. Does the packetizer
do something special with the pseudo instructions? I didn't see any special
code, but I could have missed it.

The packetizer should not do anything with these---they should not be inserted into a bundle. I'm not sure if the code in DFAPacketizer.cpp does that or not. In the Hexagon backend we originally treated CFI instructions as "solo", i.e. they could not be packetized with any other instruction. Now we simply delay the generation of these instructions until after packetization. The reason for this is that two instructions that could be packetized together were not packetized together if there was an CFI instruction in between. This was causing different code to be generated with the CFI instructions present.

In general, most pseudo instructions should have been expanded into real instructions by the time the packetizer runs. For exeptional cases, you can treat them as not being packetizable with any other instructions.

-Krzysztof

The scheduler probably didn't care about the information that caused the assertion in the packetizer.

-Krzysztof

Thanks for the explanation.

In the Hexagon backend we originally treated CFI instructions as "solo",

i.e. they could not be packetized with any other instruction. Now we
simply delay the generation of these instructions until after
packetization. The reason for this is that two instructions that could be
packetized together were not packetized together if there was an CFI
instruction in between. This was causing different code to be generated
with the CFI instructions present.

How do you delay the generation of the CFI instructions? I'm having the
same problem as you had. They really mess up my packets. I'd really
appreciate if you could point me to the code that shows where delayed
generation of CFI instructions occurs.

Thanks,

Watching from the sidelines but I’m curious too. In an ideal world codegen is independent of –g but CFI-as-instructions makes that hard. Even on non-VLIW like X86 we see instruction-scheduling differences depending on whether CFI instructions are present. All cases we’ve seen so far are innocuous but having differences at all makes it hard to write must-be-identical kinds of tests.

Thanks,

–paulr

I have a small pass that does that after everything else has been done.

Look in lib/Target/Hexagon/HexagonFrameLowering.cpp, the class name is HexagonCallFrameInformation.

Then in lib/Target/Hexagon/HexagonTargetMachine.cpp, we do:

void HexagonPassConfig::addPreEmitPass() {
   [...]
   // Add CFI instructions if necessary.
   addPass(createHexagonCallFrameInformation(), false);
}

-Krzysztof