Skip to content

Commit 44f07ae

Browse files
committed
IRGen: a small refactoring in GenConstant
Just moving a few functions around and make emitConstantValue the main entry point for creating constants. NFC
1 parent 65b03f9 commit 44f07ae

File tree

3 files changed

+64
-83
lines changed

3 files changed

+64
-83
lines changed

lib/IRGen/GenConstant.cpp

Lines changed: 60 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "GenTuple.h"
2323
#include "TypeInfo.h"
2424
#include "StructLayout.h"
25+
#include "Callee.h"
2526
#include "swift/Basic/Range.h"
2627
#include "swift/SIL/SILModule.h"
2728

@@ -109,11 +110,67 @@ llvm::Constant *irgen::emitAddrOfConstantString(IRGenModule &IGM,
109110
llvm_unreachable("bad string encoding");
110111
}
111112

112-
static llvm::Constant *emitConstantValue(IRGenModule &IGM, SILValue operand) {
113+
namespace {
114+
115+
/// Fill in the missing values for padding.
116+
void insertPadding(SmallVectorImpl<llvm::Constant *> &Elements,
117+
llvm::StructType *sTy) {
118+
// fill in any gaps, which are the explicit padding that swiftc inserts.
119+
for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
120+
auto &elt = Elements[i];
121+
if (elt == nullptr) {
122+
auto *eltTy = sTy->getElementType(i);
123+
assert(eltTy->isArrayTy() &&
124+
eltTy->getArrayElementType()->isIntegerTy(8) &&
125+
"Unexpected non-byte-array type for constant struct padding");
126+
elt = llvm::UndefValue::get(eltTy);
127+
}
128+
}
129+
}
130+
131+
template <typename InstTy, typename NextIndexFunc>
132+
llvm::Constant *emitConstantStructOrTuple(IRGenModule &IGM, InstTy inst,
133+
NextIndexFunc nextIndex) {
134+
auto type = inst->getType();
135+
auto *sTy = cast<llvm::StructType>(IGM.getTypeInfo(type).getStorageType());
136+
137+
SmallVector<llvm::Constant *, 32> elts(sTy->getNumElements(), nullptr);
138+
139+
// run over the Swift initializers, putting them into the struct as
140+
// appropriate.
141+
for (unsigned i = 0, e = inst->getElements().size(); i != e; ++i) {
142+
auto operand = inst->getOperand(i);
143+
Optional<unsigned> index = nextIndex(IGM, type, i);
144+
if (index.hasValue()) {
145+
assert(elts[index.getValue()] == nullptr &&
146+
"Unexpected constant struct field overlap");
147+
148+
elts[index.getValue()] = emitConstantValue(IGM, operand);
149+
}
150+
}
151+
insertPadding(elts, sTy);
152+
return llvm::ConstantStruct::get(sTy, elts);
153+
}
154+
} // end anonymous namespace
155+
156+
llvm::Constant *irgen::emitConstantValue(IRGenModule &IGM, SILValue operand) {
113157
if (auto *SI = dyn_cast<StructInst>(operand)) {
114-
return emitConstantStruct(IGM, SI);
158+
// The only way to get a struct's stored properties (which we need to map to
159+
// their physical/LLVM index) is to iterate over the properties
160+
// progressively. Fortunately the iteration order matches the order of
161+
// operands in a StructInst.
162+
auto StoredProperties = SI->getStructDecl()->getStoredProperties();
163+
auto Iter = StoredProperties.begin();
164+
165+
return emitConstantStructOrTuple(
166+
IGM, SI, [&Iter](IRGenModule &IGM, SILType Type, unsigned _i) mutable {
167+
(void)_i;
168+
auto *FD = *Iter++;
169+
return irgen::getPhysicalStructFieldIndex(IGM, Type, FD);
170+
});
115171
} else if (auto *TI = dyn_cast<TupleInst>(operand)) {
116-
return emitConstantTuple(IGM, TI);
172+
return emitConstantStructOrTuple(IGM, TI,
173+
irgen::getPhysicalTupleElementStructIndex);
117174
} else if (auto *ILI = dyn_cast<IntegerLiteralInst>(operand)) {
118175
return emitConstantInt(IGM, ILI);
119176
} else if (auto *FLI = dyn_cast<FloatLiteralInst>(operand)) {
@@ -164,70 +221,6 @@ static llvm::Constant *emitConstantValue(IRGenModule &IGM, SILValue operand) {
164221
}
165222
}
166223

167-
namespace {
168-
169-
/// Fill in the missing values for padding.
170-
void insertPadding(SmallVectorImpl<llvm::Constant *> &Elements,
171-
llvm::StructType *sTy) {
172-
// fill in any gaps, which are the explicit padding that swiftc inserts.
173-
for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
174-
auto &elt = Elements[i];
175-
if (elt == nullptr) {
176-
auto *eltTy = sTy->getElementType(i);
177-
assert(eltTy->isArrayTy() &&
178-
eltTy->getArrayElementType()->isIntegerTy(8) &&
179-
"Unexpected non-byte-array type for constant struct padding");
180-
elt = llvm::UndefValue::get(eltTy);
181-
}
182-
}
183-
}
184-
185-
template <typename InstTy, typename NextIndexFunc>
186-
llvm::Constant *emitConstantStructOrTuple(IRGenModule &IGM, InstTy inst,
187-
NextIndexFunc nextIndex) {
188-
auto type = inst->getType();
189-
auto *sTy = cast<llvm::StructType>(IGM.getTypeInfo(type).getStorageType());
190-
191-
SmallVector<llvm::Constant *, 32> elts(sTy->getNumElements(), nullptr);
192-
193-
// run over the Swift initializers, putting them into the struct as
194-
// appropriate.
195-
for (unsigned i = 0, e = inst->getElements().size(); i != e; ++i) {
196-
auto operand = inst->getOperand(i);
197-
Optional<unsigned> index = nextIndex(IGM, type, i);
198-
if (index.hasValue()) {
199-
assert(elts[index.getValue()] == nullptr &&
200-
"Unexpected constant struct field overlap");
201-
202-
elts[index.getValue()] = emitConstantValue(IGM, operand);
203-
}
204-
}
205-
insertPadding(elts, sTy);
206-
return llvm::ConstantStruct::get(sTy, elts);
207-
}
208-
} // end anonymous namespace
209-
210-
llvm::Constant *irgen::emitConstantStruct(IRGenModule &IGM, StructInst *SI) {
211-
// The only way to get a struct's stored properties (which we need to map to
212-
// their physical/LLVM index) is to iterate over the properties
213-
// progressively. Fortunately the iteration order matches the order of
214-
// operands in a StructInst.
215-
auto StoredProperties = SI->getStructDecl()->getStoredProperties();
216-
auto Iter = StoredProperties.begin();
217-
218-
return emitConstantStructOrTuple(
219-
IGM, SI, [&Iter](IRGenModule &IGM, SILType Type, unsigned _i) mutable {
220-
(void)_i;
221-
auto *FD = *Iter++;
222-
return irgen::getPhysicalStructFieldIndex(IGM, Type, FD);
223-
});
224-
}
225-
226-
llvm::Constant *irgen::emitConstantTuple(IRGenModule &IGM, TupleInst *TI) {
227-
return emitConstantStructOrTuple(IGM, TI,
228-
irgen::getPhysicalTupleElementStructIndex);
229-
}
230-
231224
llvm::Constant *irgen::emitConstantObject(IRGenModule &IGM, ObjectInst *OI,
232225
StructLayout *ClassLayout) {
233226
auto *sTy = cast<llvm::StructType>(ClassLayout->getType());

lib/IRGen/GenConstant.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,8 @@ llvm::Constant *emitConstantFP(IRGenModule &IGM, FloatLiteralInst *FLI);
3737
llvm::Constant *emitAddrOfConstantString(IRGenModule &IGM,
3838
StringLiteralInst *SLI);
3939

40-
/// Construct a struct literal from a StructInst containing constant values.
41-
llvm::Constant *emitConstantStruct(IRGenModule &IGM, StructInst *SI);
42-
43-
/// Construct a struct literal from a TupleInst containing constant values.
44-
llvm::Constant *emitConstantTuple(IRGenModule &IGM, TupleInst *TI);
40+
/// Construct a constant from a SILValue containing constant values.
41+
llvm::Constant *emitConstantValue(IRGenModule &IGM, SILValue value);
4542

4643
/// Construct an object (with a HeapObject header) from an ObjectInst
4744
/// containing constant values.

lib/IRGen/IRGenSIL.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6414,17 +6414,8 @@ void IRGenModule::emitSILStaticInitializers() {
64146414
continue;
64156415
}
64166416

6417-
// Set the IR global's initializer to the constant for this SIL
6418-
// struct.
6419-
if (auto *SI = dyn_cast<StructInst>(InitValue)) {
6420-
IRGlobal->setInitializer(emitConstantStruct(*this, SI));
6421-
continue;
6422-
}
6423-
6424-
// Set the IR global's initializer to the constant for this SIL
6425-
// tuple.
6426-
auto *TI = cast<TupleInst>(InitValue);
6427-
IRGlobal->setInitializer(emitConstantTuple(*this, TI));
6417+
IRGlobal->setInitializer(
6418+
emitConstantValue(*this, cast<SingleValueInstruction>(InitValue)));
64286419
}
64296420
}
64306421

0 commit comments

Comments
 (0)