bool ScopDetection::isInvariant(const Value &Val, const Region &Reg) const { // A reference to function argument or constant value is invariant. if (isa<Argument>(Val) || isa<Constant>(Val)) return true; const Instruction *I = dyn_cast<Instruction>(&Val); if (!I) return false; if (!Reg.contains(I)) return true; if (I->mayHaveSideEffects()) return false; // When Val is a Phi node, it is likely not invariant. We do not check whether // Phi nodes are actually invariant, we assume that Phi nodes are usually not // invariant. Recursively checking the operators of Phi nodes would lead to // infinite recursion. if (isa<PHINode>(*I)) return false; for (const Use &Operand : I->operands()) if (!isInvariant(*Operand, Reg)) return false; // When the instruction is a load instruction, check that no write to memory // in the region aliases with the load. if (const LoadInst *LI = dyn_cast<LoadInst>(I)) { AliasAnalysis::Location Loc = AA->getLocation(LI); const Region::const_block_iterator BE = Reg.block_end(); // Check if any basic block in the region can modify the location pointed to // by 'Loc'. If so, 'Val' is (likely) not invariant in the region. for (const BasicBlock *BB : Reg.blocks()) if (AA->canBasicBlockModify(*BB, Loc)) return false; } return true; }