Initial cut at a instruction raising patch

Hi,

This patch raises selected instructions to function calls. I've dome some preliminary testing and I works:

; ModuleID = 'raise.o'
target datalayout = "e-p:32:32-i1:8:0-i8:8:0-i16:16:0-i32:32:0-i32:32:0-i64:32:0-f32:32:0-f64:32:0-f96:32:0-v64:64:64-v128:128:0-a0:0"
target triple = "i386-pc-linux-gnu"

define i32 @main(i32, i8**, ...) nounwind {
entry:
         %argc = alloca i32 ; <i32*> [#uses=1]
         store i32 %0, i32* %argc
         %argv = alloca i8** ; <i8***> [#uses=1]
         store i8** %1, i8*** %argv
         %retval = alloca i32 ; <i32*> [#uses=2]
         store i32 0, i32* %retval
         %ll = alloca i64 ; <i64*> [#uses=3]
         %l = alloca i32 ; <i32*> [#uses=3]
         %2 = load i32* %l ; <i32> [#uses=1]
         %3 = load i32* %l ; <i32> [#uses=1]
         %4 = add i32 %2, %3 ; <i32> [#uses=1]
         store i32 %4, i32* %l
         %5 = load i64* %ll ; <i64> [#uses=1]
         %6 = load i64* %ll ; <i64> [#uses=1]
         %7 = add i64 %5, %6 ; <i64> [#uses=1]
         store i64 %7, i64* %ll
         br label %return

return: ; preds = %entry
         %8 = load i32* %retval ; <i32> [#uses=1]
         ret i32 %8
}

becomes

target datalayout = "e-p:32:32-i1:8:0-i8:8:0-i16:16:0-i32:32:0-i32:32:0-i64:32:0-f32:32:0-f64:32:0-f96:32:0-v64:64:64-v128:128:0-a0:0"
target triple = "i386-pc-linux-gnu"

define i32 @main(i32, i8**, ...) nounwind {
entry:
         %argc = alloca i32 ; <i32*> [#uses=1]
         store i32 %0, i32* %argc
         %argv = alloca i8** ; <i8***> [#uses=1]
         store i8** %1, i8*** %argv
         %retval = alloca i32 ; <i32*> [#uses=2]
         store i32 0, i32* %retval
         %ll = alloca i64 ; <i64*> [#uses=3]
         %l = alloca i32 ; <i32*> [#uses=3]
         %2 = load i32* %l ; <i32> [#uses=1]
         %3 = load i32* %l ; <i32> [#uses=1]
         %4 = tail call i32 @addl(i32 %2, i32 %3) ; <i32> [#uses=1]
         store i32 %4, i32* %l
         %5 = load i64* %ll ; <i64> [#uses=1]
         %6 = load i64* %ll ; <i64> [#uses=1]
         %7 = tail call i64 @addll(i64 %5, i64 %6) ; <i64> [#uses=1]
         store i64 %7, i64* %ll
         br label %return

return: ; preds = %entry
         %8 = load i32* %retval ; <i32> [#uses=1]
         ret i32 %8
}

declare i32 @addl(i32, i32)

declare i64 @addll(i64, i64)

Could you give me any comments/criticisms?

Thanks!

-Rich

raiseinstructions.patch (8.15 KB)

Hi,

This patch raises selected instructions to function calls. I've dome some preliminary testing and I works:

Out of curiosity, why do you want this?

-Chris

Chris Lattner wrote:

Hi,

This patch raises selected instructions to function calls. I've dome some preliminary testing and I works:

Out of curiosity, why do you want this?

I do bitcode linking of a whole program, including the soft-float and other support routines that a processor needs. During IPO, the unused support functions are removed and are gone by the time code generation happens.

I'd like to run this pass to insure that the functions are referenced properly.

Ideally I'd like to run this pass after inlining and folding, etc. But it seems to work OK if I run it about the same time internalize is run.

-Rich

How do you plan to handle things like arbitrary precision integers, etc? It seems like you'll end up duplicating a ton of codegen logic to handle this.

-Chris

Chris Lattner wrote:

How do you plan to handle things like arbitrary precision integers, etc? It seems like you'll end up duplicating a ton of codegen logic to handle this.

Maybe I'm not being very clear. I want this replacement to be done at the very last minute (before unreferenced functions are removed, of course).

I only want to catch libgcc-ish functions.

For example on the x86 (32) a function containing prinf() only needs __divdi3 and __moddi3.

I'd like the code generator to do its magic until there is no more magic to do, and then replace any 64 bit divides with the function call, for example.

Make sense?

-Rich

Chris Lattner wrote:

How do you plan to handle things like arbitrary precision integers,
etc? It seems like you'll end up duplicating a ton of codegen logic
to handle this.

Maybe I'm not being very clear. I want this replacement to be done at
the very last minute (before unreferenced functions are removed, of
course).

The last possible minute, right before isel, still has arbitrary precision integers. The right place to do something like this is in the code generator, which is where it happens.

-Chris

Chris Lattner wrote: