Hello, For the Glasgow Haskell Compiler's backend, we would like to let LLVM know that certain loads are safe to execute speculatively and hence to hoist out of loops. At the moment, there doesn't seem to be a mechanism for doing so. There seem to be two ways of implementing this: either allow arbitrary instructions to be marked as safe and have Instruction::isSafeToSpeculativelyExecute return true for those or mark memory regions and extend Value::isDereferenceablePointer to return true for those. Is either of these a good idea? Or is there some other way to do this? FWIW, I quickly prototyped instruction marking using metadata and that seemed to work well enough for us. Roman
On Jan 23, 2012, at 4:22 AM, Roman Leshchinskiy wrote:> Hello, > > For the Glasgow Haskell Compiler's backend, we would like to let LLVM know > that certain loads are safe to execute speculatively and hence to hoist > out of loops. At the moment, there doesn't seem to be a mechanism for > doing so. There seem to be two ways of implementing this: either allow > arbitrary instructions to be marked as safe and have > Instruction::isSafeToSpeculativelyExecute return true for those or mark > memory regions and extend Value::isDereferenceablePointer to return true > for those. Is either of these a good idea? Or is there some other way to > do this? FWIW, I quickly prototyped instruction marking using metadata and > that seemed to work well enough for us.I think that marking the load with metadata would make sense. Is it safe to load the pointer *anywhere*, or just "ahead of the loop"? If it is safe to move it anywhere (e.g. because it is a load from constant memory, the optimizer just doesn't know it) then using metadata makes sense. If it is a region where it is safe, then we'd need to implement something like this: http://nondot.org/sabre/LLVMNotes/MemoryUseMarkers.txt -Chris
On Mon, Jan 23, 2012 at 4:22 AM, Roman Leshchinskiy <rl at cse.unsw.edu.au> wrote:> Hello, > > For the Glasgow Haskell Compiler's backend, we would like to let LLVM know > that certain loads are safe to execute speculatively and hence to hoist > out of loops. At the moment, there doesn't seem to be a mechanism for > doing so. There seem to be two ways of implementing this: either allow > arbitrary instructions to be marked as safe and have > Instruction::isSafeToSpeculativelyExecute return true for those or mark > memory regions and extend Value::isDereferenceablePointer to return true > for those. Is either of these a good idea? Or is there some other way to > do this? FWIW, I quickly prototyped instruction marking using metadata and > that seemed to work well enough for us.BTW, we already have metadata for marking a load as invariant; see http://llvm.org/docs/LangRef.html#tbaa . -Eli
On Jan 24, 2012, at 12:39 PM, Chris Lattner wrote:> > On Jan 23, 2012, at 4:22 AM, Roman Leshchinskiy wrote: > >> Hello, >> >> For the Glasgow Haskell Compiler's backend, we would like to let LLVM know >> that certain loads are safe to execute speculatively and hence to hoist >> out of loops. At the moment, there doesn't seem to be a mechanism for >> doing so. There seem to be two ways of implementing this: either allow >> arbitrary instructions to be marked as safe and have >> Instruction::isSafeToSpeculativelyExecute return true for those or mark >> memory regions and extend Value::isDereferenceablePointer to return true >> for those. Is either of these a good idea? Or is there some other way to >> do this? FWIW, I quickly prototyped instruction marking using metadata and >> that seemed to work well enough for us. > > I think that marking the load with metadata would make sense. Is it safe to load the pointer *anywhere*, or just "ahead of the loop"? If it is safe to move it anywhere (e.g. because it is a load from constant memory, the optimizer just doesn't know it) then using metadata makes sense. If it is a region where it is safe, then we'd need to implement something like this: > http://nondot.org/sabre/LLVMNotes/MemoryUseMarkers.txtJust for the case of something being from a constant location but the compiler not knowing this, you can attach the "invariant.load" metadata to a load which lets the load be hoisted out of a loop. This is only currently done on reads from runtime constant globals so the address of the load is known to be valid. The clang commit to generate it is http://llvm.org/viewvc/llvm-project?view=rev&revision=144318 The llvm commit to use it is http://llvm.org/viewvc/llvm-project?view=rev&revision=144107 Pete> > -Chris > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
On 24/01/2012, at 20:39, Chris Lattner wrote:> On Jan 23, 2012, at 4:22 AM, Roman Leshchinskiy wrote: > >> Hello, >> >> For the Glasgow Haskell Compiler's backend, we would like to let LLVM know >> that certain loads are safe to execute speculatively and hence to hoist >> out of loops. At the moment, there doesn't seem to be a mechanism for >> doing so. There seem to be two ways of implementing this: either allow >> arbitrary instructions to be marked as safe and have >> Instruction::isSafeToSpeculativelyExecute return true for those or mark >> memory regions and extend Value::isDereferenceablePointer to return true >> for those. Is either of these a good idea? Or is there some other way to >> do this? FWIW, I quickly prototyped instruction marking using metadata and >> that seemed to work well enough for us. > > I think that marking the load with metadata would make sense. Is it safe to load the pointer *anywhere*, or just "ahead of the loop"? If it is safe to move it anywhere (e.g. because it is a load from constant memory, the optimizer just doesn't know it) then using metadata makes sense. If it is a region where it is safe, then we'd need to implement something like this: > http://nondot.org/sabre/LLVMNotes/MemoryUseMarkers.txtFor the code that GHC generates, it is safe to load the pointer anywhere in the function that contains the load and those functions don't get inlined. But that's probably too specific to GHC, a general-purpose mechanism would make more sense. I looked at llvm.lifetime.start before but it has two problems. Firstly, isDeferenceablePointer doesn't seem to take it into account so marking the memory block in question has no effect on the loads. Secondly, the memory block is quite alive when the function is entered and we definitely don't want to replace those loads with undefs. We'd want to be able to mark memory blocks as "alive here" rather than "alive from now on and dead before" and we'd want isDereferenceablePointer to use this information. Alas, this seems somewhat more difficult to implement for someone who has never done any LLVM hacking before. Roman