[LLVMdev] MIScheduler + AA: Missed scheduling opportunity in MIsNeedChainEdge. Bug? (original) (raw)

Johnson, Nicholas Paul Nicholas.Paul.Johnson at DEShawResearch.com
Wed Jul 1 12:08:02 PDT 2015


Hello,

While tuning the MIScheduler for my target, I discovered a code that unnecessarily restricts the scheduler. I think this is a bug, but I would appreciate a second opinion.

In file ScheduleDAGInstrs.cpp, the function MIsNeedChainEdge determines whether two MachineInstrs are ordered by a memory dependence. It first runs through the standard criteria (Do both instructions access memory? Does at least one store to memory? Is either access volatile? etc.), and finally queries AliasAnalysis if available.

Before reaching alias analysis, however, function isUnsafeMemoryObject pessimizes the result. In particular, isUnsafeMemoryObject returns true unless all of the pointer's underlying objects satisfy IsIdentifiedObject. This forces MIsNeedChainEdge to conservatively report true, even though AliasAnalysis could give a more precise answer in some situations. Further, it is unclear why this test even exists: it does not attempt to compare the underlying object sets to test for an alias, and the volatility check should cover all this-object-is-not-quite-memory situations.

As a simple example of why this matters, suppose that you have a function like this: void doit(int *baseptr) { baseptr[0] = 1; // store 1 baseptr[1] = 2; // store 2 }

In this example, stores 1 and 2 can be freely re-ordered. However, isUnsafeMemoryObject reports true because the underlying objects (formal parameter 'baseptr') do not satisfy IsIdentifiedObject. Nonetheless, BasicAliasAnalysis can show that derived pointers &baseptr[0] and &baseptr[1] are disjoint.

Proposed solution:

Thanks, Nick Johnson D. E. Shaw Research

diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp index 390b6d2..fcf43ca 100644 --- a/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -475,7 +475,8 @@ static inline bool isGlobalMemoryObject(AliasAnalysis *AA, MachineInstr *MI) { // to deal with (i.e. volatile object). static inline bool isUnsafeMemoryObject(MachineInstr *MI, const MachineFrameInfo *MFI,

} @@ -533,7 +536,7 @@ static bool MIsNeedChainEdge(AliasAnalysis *AA, const MachineFrameInfo *MFI, if (!MIa->hasOneMemOperand() || !MIb->hasOneMemOperand()) return true;



More information about the llvm-dev mailing list