[LLVMdev] Telling the optimizer a value is always null at the start
Carlo Kok
ck at remobjects.com
Sun Jul 13 07:50:38 PDT 2014
On Thu, Jul 10, 2014 at 11:29 AM, Philip Reames
<listmail at philipreames.com> wrote:
> Hm, I don't know of an explicit way in the IR to do this. If anyone else
> does, feel free to chime in.
>
> One approach would be to add a branch at the beginning of the function
> to an
> unreachable block. If you're testeh function started with:
> if( *ex != null) llvm_unreachable();
>
> You might get lucky and have the GVN or EarlyCSE propagate the null
> value.
> You're going to run into pass ordering problems here though. I suspect
> we'd
> drop the unreachable block before GVN runs.
Looks like, at least I tried the code below and while it removes the
unreachable, it doesn't remove the second checck. Philips code looks like
it could do this though.
>
> Are you willing to extend the optimizer? If so, adding a bit of metadata
> and the rules to propagate it in the optimizer would be pretty straight
> forward. If you need this to work from C code (rather than IR), you'd
> also
> need to pass the information through clang.
Willing for sure but I don't know enough about llvm internals yet to do
that, However it looks like the hack above will work for now. Thanks!
define void @Test(i8** %exception) {
BasicBlock24:
%0 = load i8** %exception
%1 = icmp ne i8* %0, null
br i1 %1, label %BasicBlock25, label %BasicBlock26
BasicBlock25: ; preds = %BasicBlock24
unreachable
BasicBlock26: ; preds = %BasicBlock24
call void @ExtPrintf(%String* bitcast ({ i8*, i8*, i32, [14 x i8] }*
@str22 to %String*))
call void @TestCall(i8** %exception)
%2 = load i8** %exception
%3 = icmp eq i8* %2, null
br i1 %3, label %BasicBlock28, label %BasicBlock27
BasicBlock27: ; preds = %BasicBlock26
ret void
BasicBlock28: ; preds = %BasicBlock26
call void @ExtPrintf(%String* bitcast ({ i8*, i8*, i32, [18 x i8] }*
@str23 to %String*))
ret void
}
define void @TestCall(i8** %exception) {
BasicBlock29:
%0 = load i8** %exception
%1 = icmp ne i8* %0, null
br i1 %1, label %BasicBlock30, label %BasicBlock31
BasicBlock30: ; preds = %BasicBlock29
unreachable
BasicBlock31: ; preds = %BasicBlock29
call void @ExtPrintf(%String* bitcast ({ i8*, i8*, i32, [14 x i8] }*
@str24 to %String*))
ret void
}
Into:
define void @Test(i8** nocapture readonly %exception) {
BasicBlock24:
tail call void @ExtPrintf(%String* bitcast ({ i8*, i8*, i32, [14 x i8]
}* @str22 to %String*))
tail call void @ExtPrintf(%String* bitcast ({ i8*, i8*, i32, [14 x i8]
}* @str24 to %String*))
%0 = load i8** %exception, align 4
%1 = icmp eq i8* %0, null
br i1 %1, label %BasicBlock28, label %BasicBlock27
BasicBlock27: ; preds = %BasicBlock24
ret void
BasicBlock28: ; preds = %BasicBlock24
tail call void @ExtPrintf(%String* bitcast ({ i8*, i8*, i32, [18 x i8]
}* @str23 to %String*))
ret void
}
--
Carlo Kok
RemObjects Software
More information about the llvm-dev
mailing list