[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