Skip to content

Commit 1a6d76e

Browse files
Merge pull request swiftlang#69314 from nate-chandler/opaque-values/20231020/1/coalesce-use-projections-into-phis
[AddressLowering] Allow use-projection into phi.
2 parents be0d577 + 48f4b5a commit 1a6d76e

File tree

8 files changed

+793
-98
lines changed

8 files changed

+793
-98
lines changed

docs/SIL.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4361,6 +4361,8 @@ The following types of test arguments are supported:
43614361
Example: @function[foo].block[2]
43624362
- trace: @trace <-- the first ``debug_value [trace]`` in the current function
43634363
@trace[uint] <-- the ``debug_value [trace]`` at index ``uint``
4364+
- value: @{instruction}.result <-- the first result of the instruction
4365+
@{instruction}.result[uint] <-- the result at index ``uint`` produced by the instruction
43644366
@{function}.{trace} <-- the indicated trace in the indicated function
43654367
Example: @function[bar].trace
43664368
- argument: @argument <-_ the first argument of the current block

lib/SIL/Parser/ParseTestSpecification.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,28 @@ class ParseArgumentSpecification {
343343
return OperandArgument{operand};
344344
}
345345

346+
SILValue parseResultComponent(SILInstruction *within) {
347+
if (!consumePrefix("result"))
348+
return nullptr;
349+
if (empty()) {
350+
auto result = within->getResult(0);
351+
return result;
352+
}
353+
if (auto subscript = parseSubscript()) {
354+
auto index = subscript->get<unsigned long long>();
355+
auto result = within->getResult(index);
356+
return result;
357+
}
358+
llvm_unreachable("bad suffix after 'result'!?");
359+
}
360+
361+
llvm::Optional<Argument> parseResultReference(SILInstruction *within) {
362+
auto result = parseResultComponent(within);
363+
if (!result)
364+
return llvm::None;
365+
return ValueArgument{result};
366+
}
367+
346368
SILArgument *parseBlockArgumentComponent(SILBasicBlock *block) {
347369
if (!consumePrefix("argument"))
348370
return nullptr;
@@ -414,6 +436,8 @@ class ParseArgumentSpecification {
414436
return InstructionArgument{instruction};
415437
if (auto arg = parseOperandReference(instruction))
416438
return arg;
439+
if (auto res = parseResultReference(instruction))
440+
return res;
417441
llvm_unreachable("unhandled suffix after 'instruction'!?");
418442
}
419443

lib/SILOptimizer/Mandatory/AddressLowering.cpp

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -433,51 +433,58 @@ void ValueStorageMap::replaceValue(SILValue oldValue, SILValue newValue) {
433433
}
434434

435435
#ifndef NDEBUG
436-
void ValueStorage::dump() const {
437-
llvm::dbgs() << "projectedStorageID: " << projectedStorageID << "\n";
438-
llvm::dbgs() << "projectedOperandNum: " << projectedOperandNum << "\n";
439-
llvm::dbgs() << "isDefProjection: " << isDefProjection << "\n";
440-
llvm::dbgs() << "isUseProjection: " << isUseProjection << "\n";
441-
llvm::dbgs() << "isRewritten: " << isRewritten << "\n";
442-
llvm::dbgs() << "initializes: " << initializes << "\n";
436+
void ValueStorage::print(llvm::raw_ostream &OS) const {
437+
OS << "projectedStorageID: " << projectedStorageID << "\n";
438+
OS << "projectedOperandNum: " << projectedOperandNum << "\n";
439+
OS << "isDefProjection: " << isDefProjection << "\n";
440+
OS << "isUseProjection: " << isUseProjection << "\n";
441+
OS << "isRewritten: " << isRewritten << "\n";
442+
OS << "initializes: " << initializes << "\n";
443443
}
444-
void ValueStorageMap::ValueStoragePair::dump() const {
445-
llvm::dbgs() << "value: ";
446-
value->dump();
447-
llvm::dbgs() << "address: ";
444+
void ValueStorage::dump() const { print(llvm::dbgs()); }
445+
void ValueStorageMap::ValueStoragePair::print(llvm::raw_ostream &OS) const {
446+
OS << "value: ";
447+
value->print(OS);
448+
OS << "address: ";
448449
if (storage.storageAddress)
449-
storage.storageAddress->dump();
450+
storage.storageAddress->print(OS);
450451
else
451-
llvm::dbgs() << "UNKNOWN!\n";
452-
storage.dump();
452+
OS << "UNKNOWN!\n";
453+
storage.print(OS);
453454
}
454-
void ValueStorageMap::dumpProjections(SILValue value) const {
455+
void ValueStorageMap::ValueStoragePair::dump() const { print(llvm::dbgs()); }
456+
void ValueStorageMap::printProjections(SILValue value,
457+
llvm::raw_ostream &OS) const {
455458
for (auto *pair : getProjections(value)) {
456-
pair->dump();
459+
pair->print(OS);
457460
}
458461
}
459-
void ValueStorageMap::dump() const {
460-
llvm::dbgs() << "ValueStorageMap:\n";
462+
void ValueStorageMap::dumpProjections(SILValue value) const {
463+
printProjections(value, llvm::dbgs());
464+
}
465+
void ValueStorageMap::print(llvm::raw_ostream &OS) const {
466+
OS << "ValueStorageMap:\n";
461467
for (unsigned ordinal : indices(valueVector)) {
462468
auto &valStoragePair = valueVector[ordinal];
463-
llvm::dbgs() << "value: ";
464-
valStoragePair.value->dump();
469+
OS << "value: ";
470+
valStoragePair.value->print(OS);
465471
auto &storage = valStoragePair.storage;
466472
if (storage.isUseProjection) {
467-
llvm::dbgs() << " use projection: ";
473+
OS << " use projection: ";
468474
if (!storage.isRewritten)
469-
valueVector[storage.projectedStorageID].value->dump();
475+
valueVector[storage.projectedStorageID].value->print(OS);
470476
} else if (storage.isDefProjection) {
471-
llvm::dbgs() << " def projection: ";
477+
OS << " def projection: ";
472478
if (!storage.isRewritten)
473-
valueVector[storage.projectedStorageID].value->dump();
479+
valueVector[storage.projectedStorageID].value->print(OS);
474480
}
475481
if (storage.storageAddress) {
476-
llvm::dbgs() << " storage: ";
477-
storage.storageAddress->dump();
482+
OS << " storage: ";
483+
storage.storageAddress->print(OS);
478484
}
479485
}
480486
}
487+
void ValueStorageMap::dump() const { print(llvm::dbgs()); }
481488
#endif
482489

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

14441451
SmallVector<SILValue, 4> coalescedValues;
14451452
coalescedValues.reserve(coalescedPhi.getCoalescedOperands().size());

lib/SILOptimizer/Mandatory/AddressLowering.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
#include "llvm/ADT/DenseMap.h"
1818
#include "llvm/ADT/STLExtras.h"
1919

20+
namespace llvm {
21+
class raw_ostream;
22+
}
23+
2024
namespace swift {
2125

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

201205
#ifndef NDEBUG
206+
void print(llvm::raw_ostream &OS) const;
202207
void dump() const;
203208
#endif
204209
};
@@ -215,6 +220,7 @@ class ValueStorageMap {
215220
ValueStorage storage;
216221
ValueStoragePair(SILValue v, ValueStorage s) : value(v), storage(s) {}
217222
#ifndef NDEBUG
223+
void print(llvm::raw_ostream &OS) const;
218224
void dump() const;
219225
#endif
220226
};
@@ -396,7 +402,9 @@ class ValueStorageMap {
396402
bool isComposingUseProjection(Operand *oper) const;
397403

398404
#ifndef NDEBUG
405+
void printProjections(SILValue value, llvm::raw_ostream &OS) const;
399406
void dumpProjections(SILValue value) const;
407+
void print(llvm::raw_ostream &OS) const;
400408
void dump() const;
401409
#endif
402410
};

0 commit comments

Comments
 (0)