Skip to content

[AddressLowering] Allow use-projection into phi. #69314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/SIL.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4361,6 +4361,8 @@ The following types of test arguments are supported:
Example: @function[foo].block[2]
- trace: @trace <-- the first ``debug_value [trace]`` in the current function
@trace[uint] <-- the ``debug_value [trace]`` at index ``uint``
- value: @{instruction}.result <-- the first result of the instruction
@{instruction}.result[uint] <-- the result at index ``uint`` produced by the instruction
@{function}.{trace} <-- the indicated trace in the indicated function
Example: @function[bar].trace
- argument: @argument <-_ the first argument of the current block
Expand Down
24 changes: 24 additions & 0 deletions lib/SIL/Parser/ParseTestSpecification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,28 @@ class ParseArgumentSpecification {
return OperandArgument{operand};
}

SILValue parseResultComponent(SILInstruction *within) {
if (!consumePrefix("result"))
return nullptr;
if (empty()) {
auto result = within->getResult(0);
return result;
}
if (auto subscript = parseSubscript()) {
auto index = subscript->get<unsigned long long>();
auto result = within->getResult(index);
return result;
}
llvm_unreachable("bad suffix after 'result'!?");
}

llvm::Optional<Argument> parseResultReference(SILInstruction *within) {
auto result = parseResultComponent(within);
if (!result)
return llvm::None;
return ValueArgument{result};
}

SILArgument *parseBlockArgumentComponent(SILBasicBlock *block) {
if (!consumePrefix("argument"))
return nullptr;
Expand Down Expand Up @@ -414,6 +436,8 @@ class ParseArgumentSpecification {
return InstructionArgument{instruction};
if (auto arg = parseOperandReference(instruction))
return arg;
if (auto res = parseResultReference(instruction))
return res;
llvm_unreachable("unhandled suffix after 'instruction'!?");
}

Expand Down
61 changes: 34 additions & 27 deletions lib/SILOptimizer/Mandatory/AddressLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,51 +433,58 @@ void ValueStorageMap::replaceValue(SILValue oldValue, SILValue newValue) {
}

#ifndef NDEBUG
void ValueStorage::dump() const {
llvm::dbgs() << "projectedStorageID: " << projectedStorageID << "\n";
llvm::dbgs() << "projectedOperandNum: " << projectedOperandNum << "\n";
llvm::dbgs() << "isDefProjection: " << isDefProjection << "\n";
llvm::dbgs() << "isUseProjection: " << isUseProjection << "\n";
llvm::dbgs() << "isRewritten: " << isRewritten << "\n";
llvm::dbgs() << "initializes: " << initializes << "\n";
void ValueStorage::print(llvm::raw_ostream &OS) const {
OS << "projectedStorageID: " << projectedStorageID << "\n";
OS << "projectedOperandNum: " << projectedOperandNum << "\n";
OS << "isDefProjection: " << isDefProjection << "\n";
OS << "isUseProjection: " << isUseProjection << "\n";
OS << "isRewritten: " << isRewritten << "\n";
OS << "initializes: " << initializes << "\n";
}
void ValueStorageMap::ValueStoragePair::dump() const {
llvm::dbgs() << "value: ";
value->dump();
llvm::dbgs() << "address: ";
void ValueStorage::dump() const { print(llvm::dbgs()); }
void ValueStorageMap::ValueStoragePair::print(llvm::raw_ostream &OS) const {
OS << "value: ";
value->print(OS);
OS << "address: ";
if (storage.storageAddress)
storage.storageAddress->dump();
storage.storageAddress->print(OS);
else
llvm::dbgs() << "UNKNOWN!\n";
storage.dump();
OS << "UNKNOWN!\n";
storage.print(OS);
}
void ValueStorageMap::dumpProjections(SILValue value) const {
void ValueStorageMap::ValueStoragePair::dump() const { print(llvm::dbgs()); }
void ValueStorageMap::printProjections(SILValue value,
llvm::raw_ostream &OS) const {
for (auto *pair : getProjections(value)) {
pair->dump();
pair->print(OS);
}
}
void ValueStorageMap::dump() const {
llvm::dbgs() << "ValueStorageMap:\n";
void ValueStorageMap::dumpProjections(SILValue value) const {
printProjections(value, llvm::dbgs());
}
void ValueStorageMap::print(llvm::raw_ostream &OS) const {
OS << "ValueStorageMap:\n";
for (unsigned ordinal : indices(valueVector)) {
auto &valStoragePair = valueVector[ordinal];
llvm::dbgs() << "value: ";
valStoragePair.value->dump();
OS << "value: ";
valStoragePair.value->print(OS);
auto &storage = valStoragePair.storage;
if (storage.isUseProjection) {
llvm::dbgs() << " use projection: ";
OS << " use projection: ";
if (!storage.isRewritten)
valueVector[storage.projectedStorageID].value->dump();
valueVector[storage.projectedStorageID].value->print(OS);
} else if (storage.isDefProjection) {
llvm::dbgs() << " def projection: ";
OS << " def projection: ";
if (!storage.isRewritten)
valueVector[storage.projectedStorageID].value->dump();
valueVector[storage.projectedStorageID].value->print(OS);
}
if (storage.storageAddress) {
llvm::dbgs() << " storage: ";
storage.storageAddress->dump();
OS << " storage: ";
storage.storageAddress->print(OS);
}
}
}
void ValueStorageMap::dump() const { print(llvm::dbgs()); }
#endif

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1439,7 +1446,7 @@ void OpaqueStorageAllocation::allocatePhi(PhiValue phi) {
// The phi operand projections are computed first to give them priority. Then
// we determine if the phi itself can share storage with one of its users.
CoalescedPhi coalescedPhi;
coalescedPhi.coalesce(phi, pass.valueStorageMap);
coalescedPhi.coalesce(phi, pass.valueStorageMap, pass.domInfo);

SmallVector<SILValue, 4> coalescedValues;
coalescedValues.reserve(coalescedPhi.getCoalescedOperands().size());
Expand Down
8 changes: 8 additions & 0 deletions lib/SILOptimizer/Mandatory/AddressLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"

namespace llvm {
class raw_ostream;
}

namespace swift {

/// Track an opaque value's storage. An opaque value is a SILValue with
Expand Down Expand Up @@ -199,6 +203,7 @@ struct ValueStorage {
}

#ifndef NDEBUG
void print(llvm::raw_ostream &OS) const;
void dump() const;
#endif
};
Expand All @@ -215,6 +220,7 @@ class ValueStorageMap {
ValueStorage storage;
ValueStoragePair(SILValue v, ValueStorage s) : value(v), storage(s) {}
#ifndef NDEBUG
void print(llvm::raw_ostream &OS) const;
void dump() const;
#endif
};
Expand Down Expand Up @@ -396,7 +402,9 @@ class ValueStorageMap {
bool isComposingUseProjection(Operand *oper) const;

#ifndef NDEBUG
void printProjections(SILValue value, llvm::raw_ostream &OS) const;
void dumpProjections(SILValue value) const;
void print(llvm::raw_ostream &OS) const;
void dump() const;
#endif
};
Expand Down
Loading