Skip to content

Commit 59950a6

Browse files
Merge pull request #6389 from aschwaighofer/stack_alloc_generics_07
Stack allocate generic and resilient values
2 parents d2f1de7 + a87f343 commit 59950a6

38 files changed

+1153
-305
lines changed

include/swift/IRGen/IRGenPublic.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===---------IRGenPublic.h - Public interface to IRGen ---------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
#ifndef SWIFT_IRGEN_IRGENPUBLIC_H
13+
#define SWIFT_IRGEN_IRGENPUBLIC_H
14+
15+
namespace llvm {
16+
class LLVMContext;
17+
}
18+
19+
namespace swift {
20+
class SILModule;
21+
22+
namespace irgen {
23+
24+
class IRGenerator;
25+
class IRGenModule;
26+
27+
/// Create an IRGen module.
28+
std::pair<IRGenerator *, IRGenModule *>
29+
createIRGenModule(SILModule *SILMod, llvm::LLVMContext &LLVMContext);
30+
31+
/// Delete the IRGenModule and IRGenerator obtained by the above call.
32+
void deleteIRGenModule(std::pair<IRGenerator *, IRGenModule *> &Module);
33+
34+
} // end namespace irgen
35+
} // end namespace swift
36+
37+
#endif
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===--- IRGenSILPasses.cpp - The IRGen Prepare SIL Passes ----------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
namespace swift {
14+
15+
class SILFunctionTransform;
16+
17+
namespace irgen {
18+
19+
/// Create a pass to hoist alloc_stack instructions with non-fixed size.
20+
SILFunctionTransform *createAllocStackHoisting();
21+
22+
} // end namespace irgen
23+
} // end namespace swift

include/swift/SIL/SILFunction.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,9 @@ class SILFunction
618618
SILBasicBlock &front() { return *begin(); }
619619
const SILBasicBlock &front() const { return *begin(); }
620620

621+
SILBasicBlock *getEntryBlock() { return &front(); }
622+
const SILBasicBlock *getEntryBlock() const { return &front(); }
623+
621624
SILBasicBlock *createBasicBlock();
622625
SILBasicBlock *createBasicBlock(SILBasicBlock *After);
623626

include/swift/SILOptimizer/PassManager/PassManager.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,18 @@ class SILModuleTransform;
3232
class SILOptions;
3333
class SILTransform;
3434

35+
namespace irgen {
36+
class IRGenModule;
37+
}
38+
3539
/// \brief The SIL pass manager.
3640
class SILPassManager {
3741
/// The module that the pass manager will transform.
3842
SILModule *Mod;
3943

44+
/// An optional IRGenModule associated with this PassManager.
45+
irgen::IRGenModule *IRMod;
46+
4047
/// The list of transformations to run.
4148
llvm::SmallVector<SILTransform *, 16> Transformations;
4249

@@ -90,11 +97,20 @@ class SILPassManager {
9097
/// same function.
9198
bool RestartPipeline = false;
9299

100+
101+
/// The IRGen SIL passes. These have to be dynamically added by IRGen.
102+
llvm::DenseMap<unsigned, SILFunctionTransform *> IRGenPasses;
103+
93104
public:
94105
/// C'tor. It creates and registers all analysis passes, which are defined
95106
/// in Analysis.def.
96107
SILPassManager(SILModule *M, llvm::StringRef Stage = "");
97108

109+
/// C'tor. It creates an IRGen pass manager. Passes can query for the
110+
/// IRGenModule.
111+
SILPassManager(SILModule *M, irgen::IRGenModule *IRMod,
112+
llvm::StringRef Stage = "");
113+
98114
const SILOptions &getOptions() const;
99115

100116
/// \brief Searches for an analysis of type T in the list of registered
@@ -111,6 +127,10 @@ class SILPassManager {
111127
/// \returns the module that the pass manager owns.
112128
SILModule *getModule() { return Mod; }
113129

130+
/// \returns the associated IGenModule or null if this is not an IRGen
131+
/// pass manager.
132+
irgen::IRGenModule *getIRGenModule() { return IRMod; }
133+
114134
/// \brief Run one iteration of the optimization pipeline.
115135
void runOneIteration();
116136

@@ -218,6 +238,15 @@ class SILPassManager {
218238
}
219239
}
220240

241+
void registerIRGenPass(PassKind Kind, SILFunctionTransform *Transform) {
242+
assert(IRGenPasses.find(unsigned(Kind)) == IRGenPasses.end() &&
243+
"Pass already registered");
244+
assert(
245+
IRMod &&
246+
"Attempting to register an IRGen pass with a non-IRGen pass manager");
247+
IRGenPasses[unsigned(Kind)] = Transform;
248+
}
249+
221250
private:
222251
void execute() {
223252
runOneIteration();

include/swift/SILOptimizer/PassManager/PassPipeline.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ PASSPIPELINE(OwnershipEliminator, "Utility pass to just run the ownership elimin
3535
PASSPIPELINE_WITH_OPTIONS(Performance, "Passes run at -O")
3636
PASSPIPELINE(Onone, "Passes run at -Onone")
3737
PASSPIPELINE(InstCount, "Utility pipeline to just run the inst count pass")
38+
PASSPIPELINE(IRGenPrepare, "Pipeline to run during IRGen")
3839

3940
#undef PASSPIPELINE_WITH_OPTIONS
4041
#undef PASSPIPELINE

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@
2323
#error "Macro must be defined by includer"
2424
#endif
2525

26+
/// IRGEN_PASS(Id, Name, Description)
27+
/// The pass is identified by PassKind::Id.
28+
/// An IRGen pass is created by IRGen and needs to be register with the pass
29+
/// manager dynamically.
30+
#ifndef IRGEN_PASS
31+
#define IRGEN_PASS(Id, Name, Description) PASS(Id, Name, Description)
32+
#endif
33+
2634
/// PASS_RANGE(RANGE_ID, START, END)
2735
/// Pass IDs between PassKind::START and PassKind::END, inclusive,
2836
/// fall within the set known as
@@ -36,6 +44,8 @@ PASS(ABCOpt, "abcopts",
3644
"Optimization of array bounds checks")
3745
PASS(AllocBoxToStack, "allocbox-to-stack",
3846
"Promote heap allocations to stack allocations")
47+
IRGEN_PASS(AllocStackHoisting, "alloc-stack-hoisting",
48+
"Hoist generic alloc_stack instructions to the entry block")
3949
PASS(ArrayCountPropagation, "array-count-propagation",
4050
"Propagate the count of arrays")
4151
PASS(ArrayElementPropagation, "array-element-propagation",
@@ -243,5 +253,6 @@ PASS(BugReducerTester, "bug-reducer-tester",
243253
"Utility pass for testing sil-bug-reducer. Asserts when visits an apply that calls a specific function")
244254
PASS_RANGE(AllPasses, AADumper, BugReducerTester)
245255

256+
#undef IRGEN_PASS
246257
#undef PASS
247258
#undef PASS_RANGE

include/swift/SILOptimizer/PassManager/Passes.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ namespace swift {
2323
class SILOptions;
2424
class SILTransform;
2525

26+
namespace irgen {
27+
class IRGenModule;
28+
}
29+
2630
/// \brief Run all the SIL diagnostic passes on \p M.
2731
///
2832
/// \returns true if the diagnostic passes produced an error
@@ -74,6 +78,7 @@ namespace swift {
7478
StringRef PassKindID(PassKind Kind);
7579

7680
#define PASS(ID, NAME, DESCRIPTION) SILTransform *create##ID();
81+
#define IRGEN_PASS(ID, NAME, DESCRIPTION)
7782
#include "Passes.def"
7883

7984
} // end namespace swift

include/swift/SILOptimizer/PassManager/Transforms.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ namespace swift {
116116
protected:
117117
SILFunction *getFunction() { return F; }
118118

119+
irgen::IRGenModule *getIRGenModule() {
120+
auto *Mod = PM->getIRGenModule();
121+
assert(Mod && "Expecting a valid module");
122+
return Mod;
123+
}
124+
119125
void invalidateAnalysis(SILAnalysis::InvalidationKind K) {
120126
PM->invalidateAnalysis(F, K);
121127
}

lib/IRGen/Address.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,33 @@ class ContainedAddress {
104104
bool isValid() const { return Addr.isValid(); }
105105
};
106106

107+
/// An address on the stack together with an optional stack pointer reset
108+
/// location.
109+
class StackAddress {
110+
/// The address of an object of type T.
111+
Address Addr;
112+
/// The stack pointer location to reset to when this stack object is
113+
/// deallocated.
114+
llvm::Value *StackPtrResetLocation;
115+
116+
public:
117+
StackAddress() : StackPtrResetLocation(nullptr) {}
118+
StackAddress(Address address)
119+
: Addr(address), StackPtrResetLocation(nullptr) {}
120+
StackAddress(Address address, llvm::Value *SP)
121+
: Addr(address), StackPtrResetLocation(SP) {}
122+
123+
llvm::Value *getAddressPointer() const { return Addr.getAddress(); }
124+
Alignment getAlignment() const { return Addr.getAlignment(); }
125+
Address getAddress() const { return Addr; }
126+
bool needsSPRestore() const { return StackPtrResetLocation != nullptr; }
127+
llvm::Value *getSavedSP() const {
128+
assert(StackPtrResetLocation && "Expect a valid stacksave");
129+
return StackPtrResetLocation; }
130+
131+
bool isValid() const { return Addr.isValid(); }
132+
};
133+
107134
} // end namespace irgen
108135
} // end namespace swift
109136

0 commit comments

Comments
 (0)