Skip to content

Commit 5dac59c

Browse files
committed
Move TargetConstantFolding pass to the simplification passes in Swift, enable using MemoryLayout's .size, .stride, .alignment fields in forced-const global initializers
1 parent 8626588 commit 5dac59c

File tree

14 files changed

+144
-171
lines changed

14 files changed

+144
-171
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBuiltin.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ extension BuiltinInst : OnoneSimplifyable {
2828
optimizeCanBeClass(context)
2929
case .AssertConf:
3030
optimizeAssertConfig(context)
31+
case .Sizeof,
32+
.Strideof,
33+
.Alignof:
34+
optimizeTargetTypeConst(context)
3135
default:
3236
if let literal = constantFold(context) {
3337
uses.replaceAll(with: literal, context)
@@ -131,6 +135,33 @@ private extension BuiltinInst {
131135
uses.replaceAll(with: literal, context)
132136
context.erase(instruction: self)
133137
}
138+
139+
func optimizeTargetTypeConst(_ context: SimplifyContext) {
140+
guard let ty = substitutionMap.replacementTypes[0] else {
141+
return
142+
}
143+
144+
let value: Int?
145+
switch id {
146+
case .Sizeof:
147+
value = ty.getStaticSize(context: context)
148+
case .Strideof:
149+
value = ty.getStaticStride(context: context)
150+
case .Alignof:
151+
value = ty.getStaticAlignment(context: context)
152+
default:
153+
fatalError()
154+
}
155+
156+
guard let value else {
157+
return
158+
}
159+
160+
let builder = Builder(before: self, context)
161+
let literal = builder.createIntegerLiteral(value, type: type)
162+
uses.replaceAll(with: literal, context)
163+
context.erase(instruction: self)
164+
}
134165
}
135166

136167
private func hasSideEffectForBuiltinOnce(_ instruction: Instruction) -> Bool {

SwiftCompilerSources/Sources/Optimizer/PassManager/Context.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,23 @@ struct SimplifyContext : MutatingContext {
279279
let preserveDebugInfo: Bool
280280
}
281281

282+
extension Type {
283+
func getStaticSize(context: SimplifyContext) -> Int? {
284+
let v = context._bridged.getStaticSize(self.bridged)
285+
return v == -1 ? nil : v
286+
}
287+
288+
func getStaticAlignment(context: SimplifyContext) -> Int? {
289+
let v = context._bridged.getStaticAlignment(self.bridged)
290+
return v == -1 ? nil : v
291+
}
292+
293+
func getStaticStride(context: SimplifyContext) -> Int? {
294+
let v = context._bridged.getStaticStride(self.bridged)
295+
return v == -1 ? nil : v
296+
}
297+
}
298+
282299
//===----------------------------------------------------------------------===//
283300
// Builder initialization
284301
//===----------------------------------------------------------------------===//

include/swift/SIL/SILModule.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -589,9 +589,8 @@ class SILModule {
589589

590590
const SILOptions &getOptions() const { return Options; }
591591
const IRGenOptions *getIRGenOptionsOrNull() const {
592-
// We don't want to serialize target specific SIL.
593-
assert(isSerialized() &&
594-
"Target specific options must not be used before serialization");
592+
// This exposes target specific information, therefore serialized SIL
593+
// is also target specific.
595594
return irgenOptions;
596595
}
597596

include/swift/SILOptimizer/OptimizerBridging.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,14 @@ struct BridgedPassContext {
259259
return {swift::SILUndef::get(type, *invocation->getFunction())};
260260
}
261261

262+
// IRGen
263+
264+
SwiftInt getStaticSize(swift::SILType type) const;
265+
266+
SwiftInt getStaticAlignment(swift::SILType type) const;
267+
268+
SwiftInt getStaticStride(swift::SILType type) const;
269+
262270
// Sets
263271

264272
SWIFT_IMPORT_UNSAFE

include/swift/SILOptimizer/PassManager/PassManager.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class SILCombiner;
4141

4242
namespace irgen {
4343
class IRGenModule;
44+
class IRGenerator;
4445
}
4546

4647
/// The main entrypoint for executing a pipeline pass on a SIL module.
@@ -71,6 +72,12 @@ class SwiftPassInvocation {
7172

7273
SILSSAUpdater *ssaUpdater = nullptr;
7374

75+
/// IRGen module for passes that request it (e.g. simplification pass)
76+
irgen::IRGenModule *irgenModule = nullptr;
77+
78+
/// IRGenerator used by IRGenModule above
79+
irgen::IRGenerator *irgen = nullptr;
80+
7481
static constexpr int BlockSetCapacity = 8;
7582
char blockSetStorage[sizeof(BasicBlockSet) * BlockSetCapacity];
7683
bool aliveBlockSets[BlockSetCapacity];
@@ -101,6 +108,8 @@ class SwiftPassInvocation {
101108

102109
SILFunction *getFunction() const { return function; }
103110

111+
irgen::IRGenModule *getIRGenModule();
112+
104113
FixedSizeSlab *allocSlab(FixedSizeSlab *afterSlab);
105114

106115
FixedSizeSlab *freeSlab(FixedSizeSlab *slab);

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,6 @@ PASS(ReleaseHoisting, "release-hoisting",
345345
"SIL release Hoisting")
346346
PASS(LateReleaseHoisting, "late-release-hoisting",
347347
"Late SIL release Hoisting Preserving Epilogues")
348-
PASS(TargetConstantFolding, "target-constant-folding",
349-
"Target specific constant folding")
350348
IRGEN_PASS(LoadableByAddress, "loadable-address",
351349
"SIL Large Loadable type by-address lowering.")
352350
PASS(MandatorySILLinker, "mandatory-linker",

lib/SILOptimizer/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ add_subdirectory(Analysis)
99
add_subdirectory(Differentiation)
1010
add_subdirectory(FunctionSignatureTransforms)
1111
add_subdirectory(IPO)
12-
add_subdirectory(IRGenTransforms)
1312
add_subdirectory(LoopTransforms)
1413
add_subdirectory(Mandatory)
1514
add_subdirectory(PassManager)

lib/SILOptimizer/IRGenTransforms/CMakeLists.txt

Lines changed: 0 additions & 3 deletions
This file was deleted.

lib/SILOptimizer/IRGenTransforms/TargetConstantFolding.cpp

Lines changed: 0 additions & 154 deletions
This file was deleted.

lib/SILOptimizer/PassManager/PassManager.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/AST/SILOptimizerRequests.h"
1818
#include "swift/Basic/BridgingUtils.h"
1919
#include "swift/Demangling/Demangle.h"
20+
#include "../../IRGen/IRGenModule.h"
2021
#include "swift/SIL/ApplySite.h"
2122
#include "swift/SIL/SILCloner.h"
2223
#include "swift/SIL/SILFunction.h"
@@ -1378,6 +1379,27 @@ void SwiftPassInvocation::finishedInstructionPassRun() {
13781379
endPass();
13791380
}
13801381

1382+
irgen::IRGenModule *SwiftPassInvocation::getIRGenModule() {
1383+
// We need an IRGenModule to get the actual sizes from type lowering.
1384+
// Creating an IRGenModule involves some effort, let's cache it for the
1385+
// whole pass.
1386+
if (irgenModule == nullptr && irgen == nullptr) {
1387+
SILModule *module = getPassManager()->getModule();
1388+
1389+
auto *irgenOpts = module->getIRGenOptionsOrNull();
1390+
if (!irgenOpts)
1391+
return nullptr;
1392+
1393+
irgen = new irgen::IRGenerator(*irgenOpts, *module);
1394+
auto targetMachine = irgen->createTargetMachine();
1395+
if (!targetMachine)
1396+
return nullptr;
1397+
1398+
irgenModule = new irgen::IRGenModule(*irgen, std::move(targetMachine));
1399+
}
1400+
return irgenModule;
1401+
}
1402+
13811403
void SwiftPassInvocation::endPass() {
13821404
assert(allocatedSlabs.empty() && "StackList is leaking slabs");
13831405
assert(numBlockSetsAllocated == 0 && "Not all BasicBlockSets deallocated");
@@ -1388,6 +1410,14 @@ void SwiftPassInvocation::endPass() {
13881410
delete ssaUpdater;
13891411
ssaUpdater = nullptr;
13901412
}
1413+
if (irgenModule) {
1414+
delete irgenModule;
1415+
irgenModule = nullptr;
1416+
}
1417+
if (irgen) {
1418+
delete irgen;
1419+
irgen = nullptr;
1420+
}
13911421
}
13921422

13931423
void SwiftPassInvocation::beginTransformFunction(SILFunction *function) {
@@ -1474,6 +1504,46 @@ void BridgedPassContext::inlineFunction(BridgedInstruction apply, bool mandatory
14741504
deleter);
14751505
}
14761506

1507+
static const irgen::TypeInfo &getTypeInfoOfBuiltin(swift::SILType type, irgen::IRGenModule &IGM) {
1508+
SILType lowered = IGM.getLoweredType(swift::Lowering::AbstractionPattern::getOpaque(), type.getASTType());
1509+
return IGM.getTypeInfo(lowered);
1510+
}
1511+
1512+
static SwiftInt integerValueFromConstant(llvm::Constant *c, SwiftInt add = 0) {
1513+
auto *intConst = dyn_cast_or_null<llvm::ConstantInt>(c);
1514+
if (!intConst)
1515+
return -1;
1516+
APInt value = intConst->getValue();
1517+
return value.getLimitedValue() + add;
1518+
}
1519+
1520+
SwiftInt BridgedPassContext::getStaticSize(swift::SILType type) const {
1521+
irgen::IRGenModule *IGM = invocation->getIRGenModule();
1522+
if (!IGM)
1523+
return -1;
1524+
auto &ti = getTypeInfoOfBuiltin(type, *IGM);
1525+
llvm::Constant *c = ti.getStaticSize(*IGM);
1526+
return integerValueFromConstant(c);
1527+
}
1528+
1529+
SwiftInt BridgedPassContext::getStaticAlignment(swift::SILType type) const {
1530+
irgen::IRGenModule *IGM = invocation->getIRGenModule();
1531+
if (!IGM)
1532+
return -1;
1533+
auto &ti = getTypeInfoOfBuiltin(type, *IGM);
1534+
llvm::Constant *c = ti.getStaticAlignmentMask(*IGM);
1535+
return integerValueFromConstant(c, 1);
1536+
}
1537+
1538+
SwiftInt BridgedPassContext::getStaticStride(swift::SILType type) const {
1539+
irgen::IRGenModule *IGM = invocation->getIRGenModule();
1540+
if (!IGM)
1541+
return -1;
1542+
auto &ti = getTypeInfoOfBuiltin(type, *IGM);
1543+
llvm::Constant *c = ti.getStaticStride(*IGM);
1544+
return integerValueFromConstant(c);
1545+
}
1546+
14771547
bool BridgedPassContext::specializeAppliesInFunction(BridgedFunction function, bool isMandatory) const {
14781548
return ::specializeAppliesInFunction(*function.getFunction(), invocation->getTransform(), isMandatory);
14791549
}

0 commit comments

Comments
 (0)