How to use CostModel?

Sorry if double posted… might have sent this to old mailing list address…

Sorry if double posted… might have sent this to old mailing list address…

From: Stephen Thomas <stephen.warner.thomas@gmail.com>
Date: Wed, Aug 5, 2015 at 10:39 AM
Subject: How to use CostModel?
To: LLVM Dev <llvmdev@cs.uiuc.edu>

Hi,

I’m trying to use the built-in CostModel class to estimate the number of machine instructions for each IR Instruction. To get a feel for what kind of output the CostModel pass gives, I ran it on the command line like so:

$ cat test.c
int main(){
int r = rand();
if (r > 1){
return ++r;
}
return r*86;
}

$ clang-3.6 -S -emit-llvm test.c -o test.bc

$ opt-3.6 -analyze -targetlibinfo -cost-model ./test.bc
Printing analysis ‘Target Library Information’:
Pass::print not implemented for pass: ‘Target Library Information’!
Printing analysis ‘Cost Model Analysis’ for function ‘main’:
Cost Model: Unknown cost for instruction: %1 = alloca i32, align 4
Cost Model: Unknown cost for instruction: %r = alloca i32, align 4
Cost Model: Found an estimated cost of 1 for instruction: store i32 0, i32* %1
Cost Model: Unknown cost for instruction: %2 = call i32 (…)* @rand()
Cost Model: Found an estimated cost of 1 for instruction: store i32 %2, i32* %r, align 4
Cost Model: Found an estimated cost of 1 for instruction: %3 = load i32* %r, align 4
Cost Model: Found an estimated cost of 1 for instruction: %4 = icmp sgt i32 %3, 1
Cost Model: Found an estimated cost of 0 for instruction: br i1 %4, label %5, label %8
Cost Model: Found an estimated cost of 1 for instruction: %6 = load i32* %r, align 4
Cost Model: Found an estimated cost of 1 for instruction: %7 = add nsw i32 %6, 1
Cost Model: Found an estimated cost of 1 for instruction: store i32 %7, i32* %r, align 4
Cost Model: Found an estimated cost of 1 for instruction: store i32 %7, i32* %1
Cost Model: Found an estimated cost of 0 for instruction: br label %11
Cost Model: Found an estimated cost of 1 for instruction: %9 = load i32* %r, align 4
Cost Model: Found an estimated cost of 1 for instruction: %10 = mul nsw i32 %9, 86
Cost Model: Found an estimated cost of 1 for instruction: store i32 %10, i32* %1
Cost Model: Found an estimated cost of 0 for instruction: br label %11
Cost Model: Found an estimated cost of 1 for instruction: %12 = load i32* %1
Cost Model: Found an estimated cost of 0 for instruction: ret i32 %12

Is it expected to only have 1s and 0s output?

The output looks correct. Try adding multiplication and division and you’ll see higher costs.

Also, what target architecture is being used for the estimations? (Is it auto detecting the architecture I’m on?)

When the cost model analysis uses it uses the target that the compiler driver sets. In your experiments with OPT you can request a specific target using the -mcpu and -mtriple flags. Like this:

-mcpu=core-avx2 -mtriple=x86_64-apple-darwin

You can find more examples under llvm/test/Analysis/CostModel.

-Nadav

Nadav,

Thanks for your help. I tried adding multiplication, but I’m still seeing 0s and 1s:

$ cat test.c
int main(){
int r = rand();
if (r > 1){
return r8;
}
return r
86;
}

$ clang-3.6 -S -emit-llvm test.c -o test.bc

$ opt-3.6 -analyze -targetlibinfo -cost-model ./test.bc
Printing analysis ‘Target Library Information’:
Pass::print not implemented for pass: ‘Target Library Information’!
Printing analysis ‘Cost Model Analysis’ for function ‘main’:
Cost Model: Unknown cost for instruction: %1 = alloca i32, align 4
Cost Model: Unknown cost for instruction: %r = alloca i32, align 4
Cost Model: Found an estimated cost of 1 for instruction: store i32 0, i32* %1
Cost Model: Unknown cost for instruction: %2 = call i32 (…)* @rand()
Cost Model: Found an estimated cost of 1 for instruction: store i32 %2, i32* %r, align 4
Cost Model: Found an estimated cost of 1 for instruction: %3 = load i32* %r, align 4
Cost Model: Found an estimated cost of 1 for instruction: %4 = icmp sgt i32 %3, 1
Cost Model: Found an estimated cost of 0 for instruction: br i1 %4, label %5, label %8
Cost Model: Found an estimated cost of 1 for instruction: %6 = load i32* %r, align 4
Cost Model: Found an estimated cost of 1 for instruction: %7 = mul nsw i32 %6, 8
Cost Model: Found an estimated cost of 1 for instruction: store i32 %7, i32* %1
Cost Model: Found an estimated cost of 0 for instruction: br label %11
Cost Model: Found an estimated cost of 1 for instruction: %9 = load i32* %r, align 4
Cost Model: Found an estimated cost of 1 for instruction: %10 = mul nsw i32 %9, 86
Cost Model: Found an estimated cost of 1 for instruction: store i32 %10, i32* %1
Cost Model: Found an estimated cost of 0 for instruction: br label %11
Cost Model: Found an estimated cost of 1 for instruction: %12 = load i32* %1
Cost Model: Found an estimated cost of 0 for instruction: ret i32 %12

I also tried adding setting the target with the flags you specified, but that didn’t seem to change anything:

$ opt-3.6 -analyze -mcpu=core-avx2 -mtriple=x86_64-apple-darwin -targetlibinfo -cost-model ./test.bc
Printing analysis ‘Target Library Information’:
Pass::print not implemented for pass: ‘Target Library Information’!
Printing analysis ‘Cost Model Analysis’ for function ‘main’:
Cost Model: Unknown cost for instruction: %1 = alloca i32, align 4
Cost Model: Unknown cost for instruction: %r = alloca i32, align 4
Cost Model: Found an estimated cost of 1 for instruction: store i32 0, i32* %1
Cost Model: Unknown cost for instruction: %2 = call i32 (…)* @rand()
Cost Model: Found an estimated cost of 1 for instruction: store i32 %2, i32* %r, align 4
Cost Model: Found an estimated cost of 1 for instruction: %3 = load i32* %r, align 4
Cost Model: Found an estimated cost of 1 for instruction: %4 = icmp sgt i32 %3, 1
Cost Model: Found an estimated cost of 0 for instruction: br i1 %4, label %5, label %8
Cost Model: Found an estimated cost of 1 for instruction: %6 = load i32* %r, align 4
Cost Model: Found an estimated cost of 1 for instruction: %7 = mul nsw i32 %6, 8
Cost Model: Found an estimated cost of 1 for instruction: store i32 %7, i32* %1
Cost Model: Found an estimated cost of 0 for instruction: br label %11
Cost Model: Found an estimated cost of 1 for instruction: %9 = load i32* %r, align 4
Cost Model: Found an estimated cost of 1 for instruction: %10 = mul nsw i32 %9, 86
Cost Model: Found an estimated cost of 1 for instruction: store i32 %10, i32* %1
Cost Model: Found an estimated cost of 0 for instruction: br label %11
Cost Model: Found an estimated cost of 1 for instruction: %12 = load i32* %1
Cost Model: Found an estimated cost of 0 for instruction: ret i32 %12

Any other ideas?

Thanks,
Steve

Any other ideas?

If you have the source code, then like Navdav said, you will be able
to find LLVM instructions with a cost > 1 in
llvm/test/Analysis/CostModel

You could try some arithmetic on float data types to get things with a
cost of 2, or you can try and get the vectorizer to kick in for even
higher costs.

float foo(float in) {
  float x = 14.5 * in;
  return x;
}

Gives me an fmul with a cost of 2

and,

int foo(int in[], int len) {
  for (int i = 0; i < len; i++) {
    in[i] = in[i] * 5;
  }
}

gets me some instructions with a cost of 6 for example.

HTH,
Charlie.