mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge remote-tracking branch 'origin/master' into master-next
This commit is contained in:
@@ -34,6 +34,7 @@ class SILBasicBlock :
|
||||
public llvm::ilist_node<SILBasicBlock>, public SILAllocated<SILBasicBlock> {
|
||||
friend class SILSuccessor;
|
||||
friend class SILFunction;
|
||||
friend class SILGlobalVariable;
|
||||
public:
|
||||
using InstListType = llvm::iplist<SILInstruction>;
|
||||
private:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -49,11 +49,14 @@ public:
|
||||
}
|
||||
|
||||
explicit SILCloner(SILFunction &F)
|
||||
: Builder(F), InsertBeforeBB(nullptr),
|
||||
OpenedArchetypesTracker(F) {
|
||||
: Builder(F), InsertBeforeBB(nullptr), OpenedArchetypesTracker(&F) {
|
||||
Builder.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
|
||||
}
|
||||
|
||||
explicit SILCloner(SILGlobalVariable *GlobVar)
|
||||
: Builder(GlobVar), InsertBeforeBB(nullptr),
|
||||
OpenedArchetypesTracker(nullptr) { }
|
||||
|
||||
/// Clients of SILCloner who want to know about any newly created
|
||||
/// instructions can install a SmallVector into the builder to collect them.
|
||||
void setTrackingList(SmallVectorImpl<SILInstruction*> *II) {
|
||||
@@ -641,6 +644,15 @@ SILCloner<ImplClass>::visitGlobalAddrInst(GlobalAddrInst *Inst) {
|
||||
Inst->getReferencedGlobal()));
|
||||
}
|
||||
|
||||
template<typename ImplClass>
|
||||
void
|
||||
SILCloner<ImplClass>::visitGlobalValueInst(GlobalValueInst *Inst) {
|
||||
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
||||
doPostProcess(Inst,
|
||||
getBuilder().createGlobalValue(getOpLocation(Inst->getLoc()),
|
||||
Inst->getReferencedGlobal()));
|
||||
}
|
||||
|
||||
template<typename ImplClass>
|
||||
void
|
||||
SILCloner<ImplClass>::visitIntegerLiteralInst(IntegerLiteralInst *Inst) {
|
||||
@@ -1337,6 +1349,16 @@ SILCloner<ImplClass>::visitSetDeallocatingInst(SetDeallocatingInst *Inst) {
|
||||
Inst->getAtomicity()));
|
||||
}
|
||||
|
||||
template<typename ImplClass>
|
||||
void
|
||||
SILCloner<ImplClass>::visitObjectInst(ObjectInst *Inst) {
|
||||
auto Elements = getOpValueArray<8>(Inst->getAllElements());
|
||||
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
||||
doPostProcess(Inst,
|
||||
getBuilder().createObject(getOpLocation(Inst->getLoc()), Inst->getType(),
|
||||
Elements, Inst->getBaseElements().size()));
|
||||
}
|
||||
|
||||
template<typename ImplClass>
|
||||
void
|
||||
SILCloner<ImplClass>::visitStructInst(StructInst *Inst) {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <string>
|
||||
#include "swift/SIL/SILLinkage.h"
|
||||
#include "swift/SIL/SILLocation.h"
|
||||
#include "swift/SIL/SILBasicBlock.h"
|
||||
#include "swift/SIL/SILType.h"
|
||||
#include "llvm/ADT/ilist_node.h"
|
||||
#include "llvm/ADT/ilist.h"
|
||||
@@ -38,8 +39,8 @@ class SILGlobalVariable
|
||||
public SILAllocated<SILGlobalVariable>
|
||||
{
|
||||
private:
|
||||
friend class SILBasicBlock;
|
||||
friend class SILModule;
|
||||
friend class SILBuilder;
|
||||
|
||||
/// The SIL module that the global variable belongs to.
|
||||
SILModule &Module;
|
||||
@@ -73,8 +74,16 @@ private:
|
||||
/// Whether or not this is a declaration.
|
||||
bool IsDeclaration;
|
||||
|
||||
/// The static initializer.
|
||||
SILFunction *InitializerF;
|
||||
/// If this block is not empty, the global variable has a static initializer.
|
||||
///
|
||||
/// The last instruction of this block is the top-level value of the static
|
||||
/// initializer.
|
||||
///
|
||||
/// The block is just used as a container for the instructions. So the
|
||||
/// instructions still have a parent SILBasicBlock (but no parent function).
|
||||
/// It would be somehow cleaner to just store an instruction list here and
|
||||
/// make the SILGlobalVariable the parent pointer of the instructions.
|
||||
SILBasicBlock StaticInitializerBlock;
|
||||
|
||||
SILGlobalVariable(SILModule &M, SILLinkage linkage,
|
||||
IsSerialized_t IsSerialized,
|
||||
@@ -118,9 +127,6 @@ public:
|
||||
|
||||
VarDecl *getDecl() const { return VDecl; }
|
||||
|
||||
SILFunction *getInitializer() const { return InitializerF; }
|
||||
void setInitializer(SILFunction *InitF);
|
||||
|
||||
/// Initialize the source location of the function.
|
||||
void setLocation(SILLocation L) { Location = L; }
|
||||
|
||||
@@ -137,13 +143,22 @@ public:
|
||||
return Location.getValue();
|
||||
}
|
||||
|
||||
// Helper functions to analyze the static initializer.
|
||||
static bool canBeStaticInitializer(SILFunction *F);
|
||||
/// Check if a given SILFunction can be a static initializer. If yes, return
|
||||
/// the SILGlobalVariable that it writes to.
|
||||
static SILGlobalVariable *getVariableOfStaticInitializer(SILFunction *F);
|
||||
/// Return the value that is written into the global variable.
|
||||
SILInstruction *getValueOfStaticInitializer();
|
||||
/// Returns the value of the static initializer or null if the global has no
|
||||
/// static initializer.
|
||||
SILInstruction *getStaticInitializerValue();
|
||||
|
||||
/// Returns true if the global is a statically initialized heap object.
|
||||
bool isInitializedObject() {
|
||||
return dyn_cast_or_null<ObjectInst>(getStaticInitializerValue()) != nullptr;
|
||||
}
|
||||
|
||||
/// Returns true if \p I is a valid instruction to be contained in the
|
||||
/// static initializer.
|
||||
static bool isValidStaticInitializerInst(const SILInstruction *I);
|
||||
|
||||
void dropAllReferences() {
|
||||
StaticInitializerBlock.dropAllReferences();
|
||||
}
|
||||
|
||||
/// Return whether this variable corresponds to a Clang node.
|
||||
bool hasClangNode() const;
|
||||
|
||||
@@ -138,6 +138,9 @@ public:
|
||||
SILFunction *getFunction();
|
||||
const SILFunction *getFunction() const;
|
||||
|
||||
/// Is this instruction part of a static initializer of a SILGlobalVariable?
|
||||
bool isStaticInitializerInst() const { return getFunction() == nullptr; }
|
||||
|
||||
SILModule &getModule() const;
|
||||
|
||||
/// This instruction's source location (AST node).
|
||||
@@ -1837,7 +1840,7 @@ class BuiltinInst : public SILInstruction {
|
||||
static BuiltinInst *create(SILDebugLocation DebugLoc, Identifier Name,
|
||||
SILType ReturnType,
|
||||
SubstitutionList Substitutions,
|
||||
ArrayRef<SILValue> Args, SILFunction &F);
|
||||
ArrayRef<SILValue> Args, SILModule &M);
|
||||
|
||||
public:
|
||||
/// Return the name of the builtin operation.
|
||||
@@ -1934,22 +1937,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// Gives the address of a SIL global variable. Only valid after an
|
||||
/// AllocGlobalInst.
|
||||
class GlobalAddrInst : public LiteralInst {
|
||||
friend SILBuilder;
|
||||
|
||||
/// The base class for global_addr and global_value.
|
||||
class GlobalAccessInst : public LiteralInst {
|
||||
SILGlobalVariable *Global;
|
||||
|
||||
GlobalAddrInst(SILDebugLocation DebugLoc, SILGlobalVariable *Global);
|
||||
protected:
|
||||
GlobalAccessInst(ValueKind valueKind, SILDebugLocation DebugLoc,
|
||||
SILGlobalVariable *Global, SILType Ty)
|
||||
: LiteralInst(valueKind, DebugLoc, Ty), Global(Global) { }
|
||||
|
||||
public:
|
||||
// FIXME: This constructor should be private but is currently used
|
||||
// in the SILParser.
|
||||
|
||||
/// Create a placeholder instruction with an unset global reference.
|
||||
GlobalAddrInst(SILDebugLocation DebugLoc, SILType Ty);
|
||||
|
||||
/// Return the referenced global variable.
|
||||
SILGlobalVariable *getReferencedGlobal() const { return Global; }
|
||||
|
||||
@@ -1957,12 +1954,41 @@ public:
|
||||
|
||||
ArrayRef<Operand> getAllOperands() const { return {}; }
|
||||
MutableArrayRef<Operand> getAllOperands() { return {}; }
|
||||
};
|
||||
|
||||
/// Gives the address of a SIL global variable. Only valid after an
|
||||
/// AllocGlobalInst.
|
||||
class GlobalAddrInst : public GlobalAccessInst {
|
||||
friend SILBuilder;
|
||||
|
||||
GlobalAddrInst(SILDebugLocation DebugLoc, SILGlobalVariable *Global);
|
||||
public:
|
||||
// FIXME: This constructor should be private but is currently used
|
||||
// in the SILParser.
|
||||
|
||||
/// Create a placeholder instruction with an unset global reference.
|
||||
GlobalAddrInst(SILDebugLocation DebugLoc, SILType Ty)
|
||||
: GlobalAccessInst(ValueKind::GlobalAddrInst, DebugLoc, nullptr, Ty) { }
|
||||
|
||||
static bool classof(const ValueBase *V) {
|
||||
return V->getKind() == ValueKind::GlobalAddrInst;
|
||||
}
|
||||
};
|
||||
|
||||
/// Gives the value of a global variable.
|
||||
///
|
||||
/// The referenced global variable must be a statically initialized object.
|
||||
/// TODO: in future we might support global variables in general.
|
||||
class GlobalValueInst : public GlobalAccessInst {
|
||||
friend SILBuilder;
|
||||
|
||||
GlobalValueInst(SILDebugLocation DebugLoc, SILGlobalVariable *Global);
|
||||
public:
|
||||
static bool classof(const ValueBase *V) {
|
||||
return V->getKind() == ValueKind::GlobalValueInst;
|
||||
}
|
||||
};
|
||||
|
||||
/// IntegerLiteralInst - Encapsulates an integer constant, as defined originally
|
||||
/// by an IntegerLiteralExpr.
|
||||
class IntegerLiteralInst final : public LiteralInst,
|
||||
@@ -1975,11 +2001,11 @@ class IntegerLiteralInst final : public LiteralInst,
|
||||
IntegerLiteralInst(SILDebugLocation Loc, SILType Ty, const APInt &Value);
|
||||
|
||||
static IntegerLiteralInst *create(IntegerLiteralExpr *E,
|
||||
SILDebugLocation Loc, SILFunction &B);
|
||||
SILDebugLocation Loc, SILModule &M);
|
||||
static IntegerLiteralInst *create(SILDebugLocation Loc, SILType Ty,
|
||||
intmax_t Value, SILFunction &B);
|
||||
intmax_t Value, SILModule &M);
|
||||
static IntegerLiteralInst *create(SILDebugLocation Loc, SILType Ty,
|
||||
const APInt &Value, SILFunction &B);
|
||||
const APInt &Value, SILModule &M);
|
||||
|
||||
public:
|
||||
/// getValue - Return the APInt for the underlying integer literal.
|
||||
@@ -2005,9 +2031,9 @@ class FloatLiteralInst final : public LiteralInst,
|
||||
FloatLiteralInst(SILDebugLocation Loc, SILType Ty, const APInt &Bits);
|
||||
|
||||
static FloatLiteralInst *create(FloatLiteralExpr *E, SILDebugLocation Loc,
|
||||
SILFunction &B);
|
||||
SILModule &M);
|
||||
static FloatLiteralInst *create(SILDebugLocation Loc, SILType Ty,
|
||||
const APFloat &Value, SILFunction &B);
|
||||
const APFloat &Value, SILModule &M);
|
||||
|
||||
public:
|
||||
/// \brief Return the APFloat for the underlying FP literal.
|
||||
@@ -2048,7 +2074,7 @@ private:
|
||||
Encoding encoding, SILType ty);
|
||||
|
||||
static StringLiteralInst *create(SILDebugLocation DebugLoc, StringRef Text,
|
||||
Encoding encoding, SILFunction &F);
|
||||
Encoding encoding, SILModule &M);
|
||||
|
||||
public:
|
||||
/// getValue - Return the string data for the literal, in UTF-8.
|
||||
@@ -2096,7 +2122,7 @@ private:
|
||||
|
||||
static ConstStringLiteralInst *create(SILDebugLocation DebugLoc,
|
||||
StringRef Text, Encoding encoding,
|
||||
SILFunction &F);
|
||||
SILModule &M);
|
||||
|
||||
public:
|
||||
/// getValue - Return the string data for the literal, in UTF-8.
|
||||
@@ -3615,7 +3641,7 @@ class StructInst : public SILInstruction {
|
||||
|
||||
/// Construct a StructInst.
|
||||
static StructInst *create(SILDebugLocation DebugLoc, SILType Ty,
|
||||
ArrayRef<SILValue> Elements, SILFunction &F);
|
||||
ArrayRef<SILValue> Elements, SILModule &M);
|
||||
|
||||
public:
|
||||
/// The elements referenced by this StructInst.
|
||||
@@ -3894,6 +3920,57 @@ class StrongUnpinInst
|
||||
}
|
||||
};
|
||||
|
||||
/// ObjectInst - Represents a object value type.
|
||||
///
|
||||
/// This instruction can only appear at the end of a gobal variable's
|
||||
/// static initializer list.
|
||||
class ObjectInst : public SILInstruction {
|
||||
friend SILBuilder;
|
||||
|
||||
unsigned NumBaseElements;
|
||||
|
||||
TailAllocatedOperandList<0> Operands;
|
||||
|
||||
/// Because of the storage requirements of ObjectInst, object
|
||||
/// creation goes through 'create()'.
|
||||
ObjectInst(SILDebugLocation DebugLoc, SILType Ty,
|
||||
ArrayRef<SILValue> Elements, unsigned NumBaseElements);
|
||||
|
||||
/// Construct an ObjectInst.
|
||||
static ObjectInst *create(SILDebugLocation DebugLoc, SILType Ty,
|
||||
ArrayRef<SILValue> Elements,
|
||||
unsigned NumBaseElements, SILModule &M);
|
||||
|
||||
public:
|
||||
/// All elements referenced by this ObjectInst.
|
||||
MutableArrayRef<Operand> getElementOperands() {
|
||||
return Operands.getDynamicAsArray();
|
||||
}
|
||||
|
||||
/// All elements referenced by this ObjectInst.
|
||||
OperandValueArrayRef getAllElements() const {
|
||||
return Operands.getDynamicValuesAsArray();
|
||||
}
|
||||
|
||||
/// The elements which initialize the stored properties of the object itself.
|
||||
OperandValueArrayRef getBaseElements() const {
|
||||
return Operands.getDynamicValuesAsArray().slice(0, NumBaseElements);
|
||||
}
|
||||
|
||||
/// The elements which initialize the tail allocated elements.
|
||||
OperandValueArrayRef getTailElements() const {
|
||||
return Operands.getDynamicValuesAsArray().slice(NumBaseElements);
|
||||
}
|
||||
|
||||
ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
|
||||
MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
|
||||
|
||||
static bool classof(const ValueBase *V) {
|
||||
return V->getKind() == ValueKind::ObjectInst;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// TupleInst - Represents a constructed loadable tuple.
|
||||
class TupleInst : public SILInstruction {
|
||||
friend SILBuilder;
|
||||
@@ -3907,7 +3984,7 @@ class TupleInst : public SILInstruction {
|
||||
|
||||
/// Construct a TupleInst.
|
||||
static TupleInst *create(SILDebugLocation DebugLoc, SILType Ty,
|
||||
ArrayRef<SILValue> Elements, SILFunction &F);
|
||||
ArrayRef<SILValue> Elements, SILModule &M);
|
||||
|
||||
public:
|
||||
/// The elements referenced by this TupleInst.
|
||||
|
||||
@@ -186,6 +186,7 @@ ABSTRACT_VALUE(SILInstruction, ValueBase)
|
||||
ABSTRACT_VALUE(LiteralInst, SILInstruction)
|
||||
INST(FunctionRefInst, LiteralInst, function_ref, None, DoesNotRelease)
|
||||
INST(GlobalAddrInst, LiteralInst, global_addr, None, DoesNotRelease)
|
||||
INST(GlobalValueInst, LiteralInst, global_value, None, DoesNotRelease)
|
||||
INST(IntegerLiteralInst, LiteralInst, integer_literal, None, DoesNotRelease)
|
||||
INST(FloatLiteralInst, LiteralInst, float_literal, None, DoesNotRelease)
|
||||
INST(StringLiteralInst, LiteralInst, string_literal, None, DoesNotRelease)
|
||||
@@ -212,6 +213,7 @@ ABSTRACT_VALUE(SILInstruction, ValueBase)
|
||||
INST(ObjCProtocolInst, SILInstruction, objc_protocol, None, DoesNotRelease)
|
||||
|
||||
// Aggregate Types
|
||||
INST(ObjectInst, SILInstruction, object, None, DoesNotRelease)
|
||||
INST(TupleInst, SILInstruction, tuple, None, DoesNotRelease)
|
||||
INST(TupleExtractInst, SILInstruction, tuple_extract, None, DoesNotRelease)
|
||||
INST(TupleElementAddrInst, SILInstruction, tuple_element_addr, None, DoesNotRelease)
|
||||
|
||||
@@ -37,21 +37,24 @@ public:
|
||||
: SILOpenedArchetypesTracker(Tracker.F, Tracker) {}
|
||||
|
||||
// Re-use pre-populated map if available.
|
||||
SILOpenedArchetypesTracker(const SILFunction &F,
|
||||
SILOpenedArchetypesTracker(const SILFunction *F,
|
||||
SILOpenedArchetypesTracker &Tracker)
|
||||
: F(F), OpenedArchetypeDefs(Tracker.OpenedArchetypeDefs) { }
|
||||
|
||||
// Re-use pre-populated map if available.
|
||||
SILOpenedArchetypesTracker(const SILFunction &F,
|
||||
SILOpenedArchetypesTracker(const SILFunction *F,
|
||||
OpenedArchetypeDefsMap &OpenedArchetypeDefs)
|
||||
: F(F), OpenedArchetypeDefs(OpenedArchetypeDefs) { }
|
||||
|
||||
// Use its own local map if no pre-populated map is provided.
|
||||
SILOpenedArchetypesTracker(const SILFunction &F)
|
||||
SILOpenedArchetypesTracker(const SILFunction *F)
|
||||
: F(F), OpenedArchetypeDefs(LocalOpenedArchetypeDefs) { }
|
||||
|
||||
|
||||
const SILFunction &getFunction() const { return F; }
|
||||
const SILFunction *getFunction() const {
|
||||
assert(F && "no function context available");
|
||||
return F;
|
||||
}
|
||||
|
||||
// Register a definition of a given opened archetype.
|
||||
void addOpenedArchetypeDef(CanArchetypeType archetype, SILValue Def);
|
||||
@@ -111,7 +114,8 @@ public:
|
||||
|
||||
virtual ~SILOpenedArchetypesTracker() {
|
||||
// Unregister the handler.
|
||||
F.getModule().removeDeleteNotificationHandler(this);
|
||||
if (F)
|
||||
F->getModule().removeDeleteNotificationHandler(this);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -119,7 +123,7 @@ private:
|
||||
SILOpenedArchetypesTracker &operator = (const SILOpenedArchetypesTracker &) = delete;
|
||||
/// The function whose opened archetypes are being tracked.
|
||||
/// Used only for verification purposes.
|
||||
const SILFunction &F;
|
||||
const SILFunction *F;
|
||||
|
||||
/// Mapping from opened archetypes to their definitions.
|
||||
OpenedArchetypeDefsMap &OpenedArchetypeDefs;
|
||||
|
||||
@@ -48,16 +48,9 @@ protected:
|
||||
// Cache block and value identifiers for this function. This is useful in
|
||||
// general for identifying entities, not just emitting textual SIL.
|
||||
//
|
||||
// TODO: It would be more disciplined for the caller to provide a function
|
||||
// context. That way it would be impossible for IDs to change meaning within
|
||||
// the caller's scope.
|
||||
struct SILPrintFunctionContext {
|
||||
const SILFunction *F = nullptr;
|
||||
llvm::DenseMap<const SILBasicBlock *, unsigned> BlocksToIDMap;
|
||||
llvm::DenseMap<const ValueBase *, unsigned> ValueToIDMap;
|
||||
};
|
||||
|
||||
SILPrintFunctionContext FuncCtx;
|
||||
const void *ContextFunctionOrBlock = nullptr;
|
||||
llvm::DenseMap<const SILBasicBlock *, unsigned> BlocksToIDMap;
|
||||
llvm::DenseMap<const ValueBase *, unsigned> ValueToIDMap;
|
||||
|
||||
llvm::raw_ostream &OutStream;
|
||||
|
||||
@@ -84,7 +77,7 @@ public:
|
||||
|
||||
virtual ~SILPrintContext();
|
||||
|
||||
SILPrintFunctionContext &getFuncContext(const SILFunction *F);
|
||||
void setContext(const void *FunctionOrBlock);
|
||||
|
||||
// Initialized block IDs from the order provided in `blocks`.
|
||||
void initBlockIDs(ArrayRef<const SILBasicBlock *> Blocks);
|
||||
|
||||
Reference in New Issue
Block a user