/// This returns true if the two MIs need a chain edge betwee them. /// If these are not even memory operations, we still may need /// chain deps between them. The question really is - could /// these two MIs be reordered during scheduling from memory dependency /// point of view. static bool MIsNeedChainEdge(AliasAnalysis *AA, const MachineFrameInfo *MFI, MachineInstr *MIa, MachineInstr *MIb) { // Cover a trivial case - no edge is need to itself. if (MIa == MIb) return false; if (isUnsafeMemoryObject(MIa, MFI) || isUnsafeMemoryObject(MIb, MFI)) return true; // If we are dealing with two "normal" loads, we do not need an edge // between them - they could be reordered. if (!MIa->mayStore() && !MIb->mayStore()) return false; // To this point analysis is generic. From here on we do need AA. if (!AA) return true; MachineMemOperand *MMOa = *MIa->memoperands_begin(); MachineMemOperand *MMOb = *MIb->memoperands_begin(); // FIXME: Need to handle multiple memory operands to support all targets. if (!MIa->hasOneMemOperand() || !MIb->hasOneMemOperand()) llvm_unreachable("Multiple memory operands."); // The following interface to AA is fashioned after DAGCombiner::isAlias // and operates with MachineMemOperand offset with some important // assumptions: // - LLVM fundamentally assumes flat address spaces. // - MachineOperand offset can *only* result from legalization and // cannot affect queries other than the trivial case of overlap // checking. // - These offsets never wrap and never step outside // of allocated objects. // - There should never be any negative offsets here. // // FIXME: Modify API to hide this math from "user" // FIXME: Even before we go to AA we can reason locally about some // memory objects. It can save compile time, and possibly catch some // corner cases not currently covered. assert ((MMOa->getOffset() >= 0) && "Negative MachineMemOperand offset"); assert ((MMOb->getOffset() >= 0) && "Negative MachineMemOperand offset"); int64_t MinOffset = std::min(MMOa->getOffset(), MMOb->getOffset()); int64_t Overlapa = MMOa->getSize() + MMOa->getOffset() - MinOffset; int64_t Overlapb = MMOb->getSize() + MMOb->getOffset() - MinOffset; AliasAnalysis::AliasResult AAResult = AA->alias( AliasAnalysis::Location(MMOa->getValue(), Overlapa, MMOa->getTBAAInfo()), AliasAnalysis::Location(MMOb->getValue(), Overlapb, MMOb->getTBAAInfo())); return (AAResult != AliasAnalysis::NoAlias); }