what can cause a "CPU table is not sorted" assertion

I’m trying to create a simplified 2 slot VLIW from an OR1K. The codebase I’m working with is here. I’ve created an initial MyTargetSchedule.td

def MyTargetModel : SchedMachineModel {
// HW can decode 2 instructions per cycle.
let IssueWidth = 2;
let LoadLatency = 4;
let MispredictPenalty = 16;

// This flag is set to allow the scheduler to assign a default model to
// unrecognized opcodes.
let CompleteModel = 0;

def WriteALU : SchedWrite;
def WriteBranch : SchedWrite;

let SchedModel = MyTargetModel in {
// SLOT0 can handles everything
def Slot0 : ProcResource<1>;
// SLOT1 can’t handles branches
def Slot1 : ProcResource<1>;

// Many micro-ops are capable of issuing on multiple ports.
def SlotAny : ProcResGroup<[Slot0, Slot1]>;

def : WriteRes<WriteALU, [SlotAny]> {
let Latency = 1;
let ResourceCycles =[1];

def : WriteRes<WriteBranch, [Slot0]> {
let Latency = 1;
let ResourceCycles =[1];

I’ve also changed OR1K.td to have

def : ProcessorModel<“generic”, MyTargetModel, [FeatureDiv, FeatureMul]>;
def : ProcessorModel<“or1200”, MyTargetModel, [FeatureDiv, FeatureMul]>;

No issues compiling the code. But when I run the following command I get and assertion:

llc -mcpu=mytarget hello_world.compiled.ll -debug-only=misched -mtriple=mytarget-unknown-linux-gnu

This is the offending line.

I’d really appreciate if someone could point out the problem.


Now that's weird. That list should be sorted automatically (by
utils/TableGen/SubtargetEmitter.cpp:227). And the sort seems to date
from 2005 so it's not even as if you could be using an out-of-date
llvm-tblgen by mistake.

The table should come from
$BUILD_DIR/lib/Target/MyTarget/MyTargetGenSubtargetInfo.inc. A table
named something like MyTargetSubTypeKV, I believe. I suggest you check
a few things, in roughly this order and with the help of a debugger:

  + That table really is sorted properly by the first string.
  + That is the table being used by LLVM just before the assert.
  + WTF is going on that the strcmp doesn't realise it's sorted.

I've got a very vague bet on locale, but even I can't see how that
could work. Knowing the strings that compare in an unexpected way
would certainly help though.



def : ProcessorModel<"generic", MyTargetModel, [FeatureDiv, FeatureMul]>;
def : ProcessorModel<"or1200", MyTargetModel, [FeatureDiv, FeatureMul]>;

Ah! I see the check is actually looking for a strict ordering. Could
there be 2 CPUs defined with the same name?


That is the conclusion I came to as well. I suspect that both "ProcessorModel"
and "Proc" commands are in the .td file. Something like:

  def : Proc<"generic", [FeatureMul, FeatureDiv]>;
  def : Proc<"or1201", [FeatureMul, FeatureDiv]>;
  def : ProcessorModel<"generic", MyTargetModel, [FeatureDiv, FeatureMul]>;
  def : ProcessorModel<"or1200", MyTargetModel, [FeatureDiv, FeatureMul]>;

where really only the ProcessorModel ones should be used after adding the
scheduling model.

-- Meador

Once I got home, I realized that as well.

Thanks for the help.