Merge remote-tracking branch 'origin/master' into master-next

This commit is contained in:
swift-ci
2017-08-23 10:29:34 -07:00
67 changed files with 2117 additions and 726 deletions

View File

@@ -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

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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.

View File

@@ -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)

View File

@@ -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;

View File

@@ -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);