mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
IRGen: a small refactoring in GenConstant
Just moving a few functions around and make emitConstantValue the main entry point for creating constants. NFC
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
#include "GenTuple.h"
|
#include "GenTuple.h"
|
||||||
#include "TypeInfo.h"
|
#include "TypeInfo.h"
|
||||||
#include "StructLayout.h"
|
#include "StructLayout.h"
|
||||||
|
#include "Callee.h"
|
||||||
#include "swift/Basic/Range.h"
|
#include "swift/Basic/Range.h"
|
||||||
#include "swift/SIL/SILModule.h"
|
#include "swift/SIL/SILModule.h"
|
||||||
|
|
||||||
@@ -109,11 +110,67 @@ llvm::Constant *irgen::emitAddrOfConstantString(IRGenModule &IGM,
|
|||||||
llvm_unreachable("bad string encoding");
|
llvm_unreachable("bad string encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
static llvm::Constant *emitConstantValue(IRGenModule &IGM, SILValue operand) {
|
namespace {
|
||||||
|
|
||||||
|
/// Fill in the missing values for padding.
|
||||||
|
void insertPadding(SmallVectorImpl<llvm::Constant *> &Elements,
|
||||||
|
llvm::StructType *sTy) {
|
||||||
|
// fill in any gaps, which are the explicit padding that swiftc inserts.
|
||||||
|
for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
|
||||||
|
auto &elt = Elements[i];
|
||||||
|
if (elt == nullptr) {
|
||||||
|
auto *eltTy = sTy->getElementType(i);
|
||||||
|
assert(eltTy->isArrayTy() &&
|
||||||
|
eltTy->getArrayElementType()->isIntegerTy(8) &&
|
||||||
|
"Unexpected non-byte-array type for constant struct padding");
|
||||||
|
elt = llvm::UndefValue::get(eltTy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename InstTy, typename NextIndexFunc>
|
||||||
|
llvm::Constant *emitConstantStructOrTuple(IRGenModule &IGM, InstTy inst,
|
||||||
|
NextIndexFunc nextIndex) {
|
||||||
|
auto type = inst->getType();
|
||||||
|
auto *sTy = cast<llvm::StructType>(IGM.getTypeInfo(type).getStorageType());
|
||||||
|
|
||||||
|
SmallVector<llvm::Constant *, 32> elts(sTy->getNumElements(), nullptr);
|
||||||
|
|
||||||
|
// run over the Swift initializers, putting them into the struct as
|
||||||
|
// appropriate.
|
||||||
|
for (unsigned i = 0, e = inst->getElements().size(); i != e; ++i) {
|
||||||
|
auto operand = inst->getOperand(i);
|
||||||
|
Optional<unsigned> index = nextIndex(IGM, type, i);
|
||||||
|
if (index.hasValue()) {
|
||||||
|
assert(elts[index.getValue()] == nullptr &&
|
||||||
|
"Unexpected constant struct field overlap");
|
||||||
|
|
||||||
|
elts[index.getValue()] = emitConstantValue(IGM, operand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
insertPadding(elts, sTy);
|
||||||
|
return llvm::ConstantStruct::get(sTy, elts);
|
||||||
|
}
|
||||||
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
llvm::Constant *irgen::emitConstantValue(IRGenModule &IGM, SILValue operand) {
|
||||||
if (auto *SI = dyn_cast<StructInst>(operand)) {
|
if (auto *SI = dyn_cast<StructInst>(operand)) {
|
||||||
return emitConstantStruct(IGM, SI);
|
// The only way to get a struct's stored properties (which we need to map to
|
||||||
|
// their physical/LLVM index) is to iterate over the properties
|
||||||
|
// progressively. Fortunately the iteration order matches the order of
|
||||||
|
// operands in a StructInst.
|
||||||
|
auto StoredProperties = SI->getStructDecl()->getStoredProperties();
|
||||||
|
auto Iter = StoredProperties.begin();
|
||||||
|
|
||||||
|
return emitConstantStructOrTuple(
|
||||||
|
IGM, SI, [&Iter](IRGenModule &IGM, SILType Type, unsigned _i) mutable {
|
||||||
|
(void)_i;
|
||||||
|
auto *FD = *Iter++;
|
||||||
|
return irgen::getPhysicalStructFieldIndex(IGM, Type, FD);
|
||||||
|
});
|
||||||
} else if (auto *TI = dyn_cast<TupleInst>(operand)) {
|
} else if (auto *TI = dyn_cast<TupleInst>(operand)) {
|
||||||
return emitConstantTuple(IGM, TI);
|
return emitConstantStructOrTuple(IGM, TI,
|
||||||
|
irgen::getPhysicalTupleElementStructIndex);
|
||||||
} else if (auto *ILI = dyn_cast<IntegerLiteralInst>(operand)) {
|
} else if (auto *ILI = dyn_cast<IntegerLiteralInst>(operand)) {
|
||||||
return emitConstantInt(IGM, ILI);
|
return emitConstantInt(IGM, ILI);
|
||||||
} else if (auto *FLI = dyn_cast<FloatLiteralInst>(operand)) {
|
} else if (auto *FLI = dyn_cast<FloatLiteralInst>(operand)) {
|
||||||
@@ -164,70 +221,6 @@ static llvm::Constant *emitConstantValue(IRGenModule &IGM, SILValue operand) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
/// Fill in the missing values for padding.
|
|
||||||
void insertPadding(SmallVectorImpl<llvm::Constant *> &Elements,
|
|
||||||
llvm::StructType *sTy) {
|
|
||||||
// fill in any gaps, which are the explicit padding that swiftc inserts.
|
|
||||||
for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
|
|
||||||
auto &elt = Elements[i];
|
|
||||||
if (elt == nullptr) {
|
|
||||||
auto *eltTy = sTy->getElementType(i);
|
|
||||||
assert(eltTy->isArrayTy() &&
|
|
||||||
eltTy->getArrayElementType()->isIntegerTy(8) &&
|
|
||||||
"Unexpected non-byte-array type for constant struct padding");
|
|
||||||
elt = llvm::UndefValue::get(eltTy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InstTy, typename NextIndexFunc>
|
|
||||||
llvm::Constant *emitConstantStructOrTuple(IRGenModule &IGM, InstTy inst,
|
|
||||||
NextIndexFunc nextIndex) {
|
|
||||||
auto type = inst->getType();
|
|
||||||
auto *sTy = cast<llvm::StructType>(IGM.getTypeInfo(type).getStorageType());
|
|
||||||
|
|
||||||
SmallVector<llvm::Constant *, 32> elts(sTy->getNumElements(), nullptr);
|
|
||||||
|
|
||||||
// run over the Swift initializers, putting them into the struct as
|
|
||||||
// appropriate.
|
|
||||||
for (unsigned i = 0, e = inst->getElements().size(); i != e; ++i) {
|
|
||||||
auto operand = inst->getOperand(i);
|
|
||||||
Optional<unsigned> index = nextIndex(IGM, type, i);
|
|
||||||
if (index.hasValue()) {
|
|
||||||
assert(elts[index.getValue()] == nullptr &&
|
|
||||||
"Unexpected constant struct field overlap");
|
|
||||||
|
|
||||||
elts[index.getValue()] = emitConstantValue(IGM, operand);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
insertPadding(elts, sTy);
|
|
||||||
return llvm::ConstantStruct::get(sTy, elts);
|
|
||||||
}
|
|
||||||
} // end anonymous namespace
|
|
||||||
|
|
||||||
llvm::Constant *irgen::emitConstantStruct(IRGenModule &IGM, StructInst *SI) {
|
|
||||||
// The only way to get a struct's stored properties (which we need to map to
|
|
||||||
// their physical/LLVM index) is to iterate over the properties
|
|
||||||
// progressively. Fortunately the iteration order matches the order of
|
|
||||||
// operands in a StructInst.
|
|
||||||
auto StoredProperties = SI->getStructDecl()->getStoredProperties();
|
|
||||||
auto Iter = StoredProperties.begin();
|
|
||||||
|
|
||||||
return emitConstantStructOrTuple(
|
|
||||||
IGM, SI, [&Iter](IRGenModule &IGM, SILType Type, unsigned _i) mutable {
|
|
||||||
(void)_i;
|
|
||||||
auto *FD = *Iter++;
|
|
||||||
return irgen::getPhysicalStructFieldIndex(IGM, Type, FD);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
llvm::Constant *irgen::emitConstantTuple(IRGenModule &IGM, TupleInst *TI) {
|
|
||||||
return emitConstantStructOrTuple(IGM, TI,
|
|
||||||
irgen::getPhysicalTupleElementStructIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
llvm::Constant *irgen::emitConstantObject(IRGenModule &IGM, ObjectInst *OI,
|
llvm::Constant *irgen::emitConstantObject(IRGenModule &IGM, ObjectInst *OI,
|
||||||
StructLayout *ClassLayout) {
|
StructLayout *ClassLayout) {
|
||||||
auto *sTy = cast<llvm::StructType>(ClassLayout->getType());
|
auto *sTy = cast<llvm::StructType>(ClassLayout->getType());
|
||||||
|
|||||||
@@ -37,11 +37,8 @@ llvm::Constant *emitConstantFP(IRGenModule &IGM, FloatLiteralInst *FLI);
|
|||||||
llvm::Constant *emitAddrOfConstantString(IRGenModule &IGM,
|
llvm::Constant *emitAddrOfConstantString(IRGenModule &IGM,
|
||||||
StringLiteralInst *SLI);
|
StringLiteralInst *SLI);
|
||||||
|
|
||||||
/// Construct a struct literal from a StructInst containing constant values.
|
/// Construct a constant from a SILValue containing constant values.
|
||||||
llvm::Constant *emitConstantStruct(IRGenModule &IGM, StructInst *SI);
|
llvm::Constant *emitConstantValue(IRGenModule &IGM, SILValue value);
|
||||||
|
|
||||||
/// Construct a struct literal from a TupleInst containing constant values.
|
|
||||||
llvm::Constant *emitConstantTuple(IRGenModule &IGM, TupleInst *TI);
|
|
||||||
|
|
||||||
/// Construct an object (with a HeapObject header) from an ObjectInst
|
/// Construct an object (with a HeapObject header) from an ObjectInst
|
||||||
/// containing constant values.
|
/// containing constant values.
|
||||||
|
|||||||
@@ -6414,17 +6414,8 @@ void IRGenModule::emitSILStaticInitializers() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the IR global's initializer to the constant for this SIL
|
IRGlobal->setInitializer(
|
||||||
// struct.
|
emitConstantValue(*this, cast<SingleValueInstruction>(InitValue)));
|
||||||
if (auto *SI = dyn_cast<StructInst>(InitValue)) {
|
|
||||||
IRGlobal->setInitializer(emitConstantStruct(*this, SI));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the IR global's initializer to the constant for this SIL
|
|
||||||
// tuple.
|
|
||||||
auto *TI = cast<TupleInst>(InitValue);
|
|
||||||
IRGlobal->setInitializer(emitConstantTuple(*this, TI));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user