mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Get rid of address to pointer conversion in LoopRotate which is present just to avoid the address phi absence assert
This commit is contained in:
@@ -147,9 +147,7 @@ static void mapOperands(SILInstruction *inst,
|
||||
static void updateSSAForUseOfValue(
|
||||
SILSSAUpdater &updater, SmallVectorImpl<SILPhiArgument *> &insertedPhis,
|
||||
const llvm::DenseMap<ValueBase *, SILValue> &valueMap,
|
||||
SILBasicBlock *Header, SILBasicBlock *EntryCheckBlock, SILValue Res,
|
||||
SmallVectorImpl<std::pair<SILBasicBlock *, unsigned>>
|
||||
&accumulatedAddressPhis) {
|
||||
SILBasicBlock *Header, SILBasicBlock *EntryCheckBlock, SILValue Res) {
|
||||
// Find the mapped instruction.
|
||||
assert(valueMap.count(Res) && "Expected to find value in map!");
|
||||
SILValue MappedValue = valueMap.find(Res)->second;
|
||||
@@ -179,14 +177,13 @@ static void updateSSAForUseOfValue(
|
||||
if (user->getParent() == Header)
|
||||
continue;
|
||||
|
||||
assert(user->getParent() != EntryCheckBlock
|
||||
&& "The entry check block should dominate the header");
|
||||
assert(user->getParent() != EntryCheckBlock &&
|
||||
"The entry check block should dominate the header");
|
||||
updater.rewriteUse(*use);
|
||||
}
|
||||
|
||||
// Canonicalize inserted phis to avoid extra BB Args and if we find an address
|
||||
// phi, stash it so we can handle it after we are done rewriting.
|
||||
bool hasOwnership = Header->getParent()->hasOwnership();
|
||||
for (SILPhiArgument *arg : insertedPhis) {
|
||||
if (SILValue inst = replaceBBArgWithCast(arg)) {
|
||||
arg->replaceAllUsesWith(inst);
|
||||
@@ -195,30 +192,24 @@ static void updateSSAForUseOfValue(
|
||||
// SimplifyCFG deletes the dead BB arg.
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we didn't simplify and have an address phi, stash the value so we can
|
||||
// fix it up.
|
||||
if (hasOwnership && arg->getType().isAddress())
|
||||
accumulatedAddressPhis.emplace_back(arg->getParent(), arg->getIndex());
|
||||
}
|
||||
}
|
||||
|
||||
static void updateSSAForUseOfInst(
|
||||
SILSSAUpdater &updater, SmallVectorImpl<SILPhiArgument *> &insertedPhis,
|
||||
const llvm::DenseMap<ValueBase *, SILValue> &valueMap,
|
||||
SILBasicBlock *header, SILBasicBlock *entryCheckBlock, SILInstruction *inst,
|
||||
SmallVectorImpl<std::pair<SILBasicBlock *, unsigned>>
|
||||
&accumulatedAddressPhis) {
|
||||
static void
|
||||
updateSSAForUseOfInst(SILSSAUpdater &updater,
|
||||
SmallVectorImpl<SILPhiArgument *> &insertedPhis,
|
||||
const llvm::DenseMap<ValueBase *, SILValue> &valueMap,
|
||||
SILBasicBlock *header, SILBasicBlock *entryCheckBlock,
|
||||
SILInstruction *inst) {
|
||||
for (auto result : inst->getResults())
|
||||
updateSSAForUseOfValue(updater, insertedPhis, valueMap, header,
|
||||
entryCheckBlock, result, accumulatedAddressPhis);
|
||||
entryCheckBlock, result);
|
||||
}
|
||||
|
||||
/// Rewrite the code we just created in the preheader and update SSA form.
|
||||
static void rewriteNewLoopEntryCheckBlock(
|
||||
SILBasicBlock *header, SILBasicBlock *entryCheckBlock,
|
||||
const llvm::DenseMap<ValueBase *, SILValue> &valueMap) {
|
||||
SmallVector<std::pair<SILBasicBlock *, unsigned>, 8> accumulatedAddressPhis;
|
||||
SmallVector<SILPhiArgument *, 8> insertedPhis;
|
||||
SILSSAUpdater updater(&insertedPhis);
|
||||
|
||||
@@ -227,7 +218,7 @@ static void rewriteNewLoopEntryCheckBlock(
|
||||
for (unsigned i : range(header->getNumArguments())) {
|
||||
auto *arg = header->getArguments()[i];
|
||||
updateSSAForUseOfValue(updater, insertedPhis, valueMap, header,
|
||||
entryCheckBlock, arg, accumulatedAddressPhis);
|
||||
entryCheckBlock, arg);
|
||||
}
|
||||
|
||||
auto instIter = header->begin();
|
||||
@@ -236,43 +227,9 @@ static void rewriteNewLoopEntryCheckBlock(
|
||||
while (instIter != header->end()) {
|
||||
auto &inst = *instIter;
|
||||
updateSSAForUseOfInst(updater, insertedPhis, valueMap, header,
|
||||
entryCheckBlock, &inst, accumulatedAddressPhis);
|
||||
entryCheckBlock, &inst);
|
||||
++instIter;
|
||||
}
|
||||
|
||||
// Then see if any of our phis were address phis. In such a case, rewrite the
|
||||
// address to be a smuggled through raw pointer. We do this late to
|
||||
// conservatively not interfere with the previous code's invariants.
|
||||
//
|
||||
// We also translate the phis into a BasicBlock, Index form so we are careful
|
||||
// with invalidation issues around branches/args.
|
||||
auto rawPointerTy =
|
||||
SILType::getRawPointerType(header->getParent()->getASTContext());
|
||||
auto rawPointerUndef = SILUndef::get(rawPointerTy, header->getModule());
|
||||
auto loc = RegularLocation::getAutoGeneratedLocation();
|
||||
while (!accumulatedAddressPhis.empty()) {
|
||||
SILBasicBlock *block;
|
||||
unsigned argIndex;
|
||||
std::tie(block, argIndex) = accumulatedAddressPhis.pop_back_val();
|
||||
auto *arg = cast<SILPhiArgument>(block->getArgument(argIndex));
|
||||
assert(arg->getType().isAddress() && "Not an address phi?!");
|
||||
for (auto *predBlock : block->getPredecessorBlocks()) {
|
||||
Operand *predUse = arg->getIncomingPhiOperand(predBlock);
|
||||
SILBuilderWithScope builder(predUse->getUser());
|
||||
auto *newIncomingValue =
|
||||
builder.createAddressToPointer(loc, predUse->get(), rawPointerTy);
|
||||
predUse->set(newIncomingValue);
|
||||
}
|
||||
SILBuilderWithScope builder(arg->getNextInstruction());
|
||||
SILType oldArgType = arg->getType();
|
||||
auto *phiShim = builder.createPointerToAddress(
|
||||
loc, rawPointerUndef, oldArgType, true /*isStrict*/,
|
||||
false /*is invariant*/);
|
||||
arg->replaceAllUsesWith(phiShim);
|
||||
SILArgument *newArg = block->replacePhiArgument(
|
||||
argIndex, rawPointerTy, OwnershipKind::None, nullptr);
|
||||
phiShim->setOperand(newArg);
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the dominator tree after rotating the loop.
|
||||
|
||||
Reference in New Issue
Block a user