// Get the aggregate member based on the top of the projection stack. static SILValue getMember(SILInstruction *inst, ProjectionPath &projStack) { if (!projStack.empty()) { const Projection &proj = projStack.back(); return proj.getOperandForAggregate(inst); } return SILValue(); }
SILValue ConstantTracker::getStoredValue(SILInstruction *loadInst, ProjectionPath &projStack) { SILInstruction *store = links[loadInst]; if (!store && callerTracker) store = callerTracker->links[loadInst]; if (!store) return SILValue(); assert(isa<LoadInst>(loadInst) || isa<CopyAddrInst>(loadInst)); // Push the address projections of the load onto the stack. SmallVector<Projection, 4> loadProjections; scanProjections(loadInst->getOperand(0), &loadProjections); for (const Projection &proj : loadProjections) { projStack.push_back(proj); } // Pop the address projections of the store from the stack. SmallVector<Projection, 4> storeProjections; scanProjections(store->getOperand(1), &storeProjections); for (auto iter = storeProjections.rbegin(); iter != storeProjections.rend(); ++iter) { const Projection &proj = *iter; // The corresponding load-projection must match the store-projection. if (projStack.empty() || projStack.back() != proj) return SILValue(); projStack.pop_back(); } if (isa<StoreInst>(store)) return store->getOperand(0); // The copy_addr instruction is both a load and a store. So we follow the link // again. assert(isa<CopyAddrInst>(store)); return getStoredValue(store, projStack); }