Skip to content

Commit

Permalink
Revert "New SIL instructions to support tail-allocated arrays in SIL."
Browse files Browse the repository at this point in the history
  • Loading branch information
gribozavr authored Sep 15, 2016
1 parent cd07c2c commit fbb3cf3
Show file tree
Hide file tree
Showing 68 changed files with 1,148 additions and 1,473 deletions.
2 changes: 2 additions & 0 deletions docs/Runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ Rename with a non-`stdlib` naming scheme.
000000000001cb30 T _swift_allocBox
000000000001c990 T _swift_allocObject
000000000001ca60 T _swift_bufferAllocate
000000000001ca70 T _swift_bufferAllocateOnStack
000000000001ca80 T _swift_bufferDeallocateFromStack
000000000001ca90 T _swift_bufferHeaderSize
000000000001cd30 T _swift_deallocBox
000000000001d490 T _swift_deallocClassInstance
Expand Down
61 changes: 1 addition & 60 deletions docs/SIL.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1828,24 +1828,16 @@ alloc_ref
`````````
::

sil-instruction ::= 'alloc_ref'
('[' 'objc' ']')?
('[' 'stack' ']')?
('[' 'tail_elems' sil-type '*' sil-operand ']')*
sil-type
sil-instruction ::= 'alloc_ref' ('[' 'objc' ']')? ('[' 'stack' ']')? sil-type

%1 = alloc_ref [stack] $T
%1 = alloc_ref [tail_elems $E * %2 : Builtin.Word] $T
// $T must be a reference type
// %1 has type $T
// $E is the type of the tail-allocated elements
// %2 must be of a builtin integer type

Allocates an object of reference type ``T``. The object will be initialized
with retain count 1; its state will be otherwise uninitialized. The
optional ``objc`` attribute indicates that the object should be
allocated using Objective-C's allocation methods (``+allocWithZone:``).

The optional ``stack`` attribute indicates that the object can be allocated
on the stack instead on the heap. In this case the instruction must have
balanced with a ``dealloc_ref [stack]`` instruction to mark the end of the
Expand All @@ -1855,15 +1847,6 @@ possible. The final decision on stack allocation is done during llvm IR
generation. This is because the decision also depends on the object size,
which is not necessarily known at SIL level.

The optional ``tail_elems`` attributes specifies the amount of space to be
reserved for tail-allocated arrays of given element types and element counts.
If there are more than one ``tail_elems`` attributes then the tail arrays are
allocated in the specified order.
The count-operand must be of a builtin integer type.
The instructions ``ref_tail_addr`` and ``tail_addr`` can be used to project
the tail elements.
The ``objc`` attribute cannot be used together with ``tail_elems``.

alloc_ref_dynamic
`````````````````
::
Expand Down Expand Up @@ -2346,31 +2329,6 @@ special behavior in this regard, unlike ``char*`` or ``void*`` in C.) It is
also undefined behavior to index out of bounds of an array, except to index
the "past-the-end" address of the array.

tail_addr
`````````
::

sil-instruction ::= 'tail_addr' sil-operand ',' sil-operand ',' sil-type

%2 = tail_addr %0 : $*T, %1 : $Builtin.Int<n>, $E
// %0 must be of an address type $*T
// %1 must be of a builtin integer type
// %2 will be of type $*E

Given an address of an array of ``%1`` values, returns the address of an
element which is tail-allocated after the array.
This instruction is equivalent to ``index_addr`` except that the resulting
address is aligned-up to the tail-element type ``$E``.

This instruction is used to project the N-th tail-allocated array from an
object which is created by an ``alloc_ref`` with multiple ``tail_elems``.
The first operand is the address of an element of the (N-1)-th array, usually
the first element. The second operand is the number of elements until the end
of that array. The result is the address of the first element of the N-th array.

It is undefined behavior if the provided address, count and type do not match
the actual layout of tail-allocated arrays of the underlying object.

index_raw_pointer
`````````````````
::
Expand Down Expand Up @@ -3298,23 +3256,6 @@ Given an instance of a class, derives the address of a physical instance
variable inside the instance. It is undefined behavior if the class value
is null.

ref_tail_addr
`````````````
::

sil-instruction ::= 'ref_tail_addr' sil-operand ',' sil-type

%1 = ref_tail_addr %0 : $C, $E
// %0 must be a value of class type $C with tail-allocated elements $E
// %1 will be of type $*E

Given an instance of a class, which is created with tail-allocated array(s),
derives the address of the first element of the first tail-allocated array.
This instruction is used to project the first tail-allocated element from an
object which is created by an ``alloc_ref`` with ``tail_elems``.
It is undefined behavior if the class instance does not have tail-allocated
arrays or if the element-types do not match.

Enums
~~~~~

Expand Down
28 changes: 1 addition & 27 deletions include/swift/AST/Builtins.def
Original file line number Diff line number Diff line change
Expand Up @@ -252,23 +252,9 @@ BUILTIN_SIL_OPERATION(ReinterpretCast, "reinterpretCast", Special)
/// valid within the scope of the statement for logical lvalues.
BUILTIN_SIL_OPERATION(AddressOf, "addressof", Special)

/// GepRaw(Builtin.RawPointer, Builtin.Word) -> Builtin.RawPointer
///
/// Adds index bytes to a base pointer.
BUILTIN_SIL_OPERATION(GepRaw, "gepRaw", Integer)

/// Gep (Builtin.RawPointer, Builtin.Word, T.Type) -> Builtin.RawPointer
///
/// Like the GepRaw-bultin, but multiplies the index by stride-of type 'T'.
/// GetElementPtr has type (Builtin.RawPointer, T) -> Builtin.RawPointer
BUILTIN_SIL_OPERATION(Gep, "gep", Integer)

/// getTailAddr(Builtin.RawPointer,
/// Builtin.Word, T.Type, E.Type) -> Builtin.RawPointer
///
/// Like the Gep-builtin, but rounds up the resulting address to a tail-
/// allocated element type 'E'.
BUILTIN_SIL_OPERATION(GetTailAddr, "getTailAddr", Integer)

/// condfail(Int1) -> ()
/// Triggers a runtime failure if the condition is true.
BUILTIN_SIL_OPERATION(CondFail, "condfail", Special)
Expand Down Expand Up @@ -328,18 +314,6 @@ BUILTIN_SIL_OPERATION(IsUniqueOrPinned_native, "isUniqueOrPinned_native",
/// bindMemory : <T> (Builtin.RawPointer, Builtin.Word, T.Type) -> ()
BUILTIN_SIL_OPERATION(BindMemory, "bindMemory", Special)

/// allocWithTailElems_<n>(C.Type,
/// Builtin.Word, E1.Type, ... , Builtin.Word, En.Type) -> C\
///
/// The integer suffix <n> specifies the number of tail-allocated arrays.
/// Each tail-allocated array adds a counter and an element meta-type parameter.
BUILTIN_SIL_OPERATION(AllocWithTailElems, "allocWithTailElems", Special)

/// projectTailElems : <C,E> (C) -> Builtin.RawPointer
///
/// Projects the first tail-allocated element of type E from a class C.
BUILTIN_SIL_OPERATION(ProjectTailElems, "projectTailElems", Special)

#undef BUILTIN_SIL_OPERATION

// BUILTIN_RUNTIME_CALL - A call into a runtime function.
Expand Down
2 changes: 0 additions & 2 deletions include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -511,8 +511,6 @@ ERROR(sil_too_many_substitutions,none,
"too many substitutions", ())
ERROR(sil_dbg_unknown_key,none,
"unknown key '%0' in debug variable declaration", (StringRef))
ERROR(sil_objc_with_tail_elements,none,
"alloc_ref [objc] cannot have tail allocated elements", ())

// SIL Basic Blocks
ERROR(expected_sil_block_name,none,
Expand Down
8 changes: 8 additions & 0 deletions include/swift/LLVMPasses/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ namespace swift {
SwiftARCContract() : llvm::FunctionPass(ID) {}
};

class SwiftStackPromotion : public llvm::FunctionPass {
virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override;
virtual bool runOnFunction(llvm::Function &F) override;
public:
static char ID;
SwiftStackPromotion() : llvm::FunctionPass(ID) {}
};

class InlineTreePrinter : public llvm::ModulePass {
virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const override;
virtual bool runOnModule(llvm::Module &M) override;
Expand Down
2 changes: 2 additions & 0 deletions include/swift/LLVMPasses/PassesFwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ namespace llvm {
void initializeSwiftRCIdentityPass(PassRegistry &);
void initializeSwiftARCOptPass(PassRegistry &);
void initializeSwiftARCContractPass(PassRegistry &);
void initializeSwiftStackPromotionPass(PassRegistry &);
void initializeInlineTreePrinterPass(PassRegistry &);
void initializeSwiftMergeFunctionsPass(PassRegistry &);
}

namespace swift {
llvm::FunctionPass *createSwiftARCOptPass();
llvm::FunctionPass *createSwiftARCContractPass();
llvm::FunctionPass *createSwiftStackPromotionPass();
llvm::ModulePass *createInlineTreePrinterPass();
llvm::ModulePass *createSwiftMergeFunctionsPass();
llvm::ImmutablePass *createSwiftAAWrapperPass();
Expand Down
8 changes: 0 additions & 8 deletions include/swift/SIL/InstructionUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@ namespace swift {
/// Strip off casts/indexing insts/address projections from V until there is
/// nothing left to strip.
SILValue getUnderlyingObject(SILValue V);

/// Strip off indexing and address projections.
///
/// This is similar to getUnderlyingObject, except that it does not strip any
/// object-to-address projections, like ref_element_addr. In other words, the
/// result is always an address value.
SILValue getUnderlyingAddressRoot(SILValue V);

SILValue getUnderlyingObjectStopAtMarkDependence(SILValue V);

SILValue stripSinglePredecessorArgs(SILValue V);
Expand Down
33 changes: 7 additions & 26 deletions include/swift/SIL/Projection.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,8 @@ enum class ProjectionKind : unsigned {
Upcast = 0,
RefCast = 1,
BitwiseCast = 2,
TailElems = 3,
FirstPointerKind = Upcast,
LastPointerKind = TailElems,
LastPointerKind = BitwiseCast,

// Index Projection Kinds
FirstIndexKind = 7,
Expand Down Expand Up @@ -125,7 +124,6 @@ static inline bool isCastProjectionKind(ProjectionKind Kind) {
case ProjectionKind::Class:
case ProjectionKind::Enum:
case ProjectionKind::Box:
case ProjectionKind::TailElems:
return false;
}
}
Expand Down Expand Up @@ -160,12 +158,6 @@ struct ProjectionIndex {
Aggregate = REA->getOperand();
break;
}
case ValueKind::RefTailAddrInst: {
RefTailAddrInst *REA = cast<RefTailAddrInst>(V);
Index = 0;
Aggregate = REA->getOperand();
break;
}
case ValueKind::ProjectBoxInst: {
ProjectBoxInst *PBI = cast<ProjectBoxInst>(V);
// A box has only a single payload.
Expand Down Expand Up @@ -301,7 +293,6 @@ class Projection {
case ProjectionKind::Upcast:
case ProjectionKind::RefCast:
case ProjectionKind::BitwiseCast:
case ProjectionKind::TailElems:
return getCastType(BaseType);
case ProjectionKind::Index:
// Index types do not change the underlying type.
Expand Down Expand Up @@ -332,19 +323,13 @@ class Projection {

SILType getCastType(SILType BaseType) const {
assert(isValid());
assert(getKind() == ProjectionKind::Upcast ||
getKind() == ProjectionKind::RefCast ||
getKind() == ProjectionKind::BitwiseCast);
auto *Ty = getPointer();
assert(Ty->isCanonical());
switch (getKind()) {
case ProjectionKind::Upcast:
case ProjectionKind::RefCast:
case ProjectionKind::BitwiseCast:
return SILType::getPrimitiveType(Ty->getCanonicalType(),
BaseType.getCategory());
case ProjectionKind::TailElems:
return SILType::getPrimitiveAddressType(Ty->getCanonicalType());
default:
llvm_unreachable("unknown cast projection type");
}
return SILType::getPrimitiveType(Ty->getCanonicalType(),
BaseType.getCategory());
}

bool operator<(const Projection &Other) const;
Expand Down Expand Up @@ -377,7 +362,6 @@ class Projection {
}
case ValueKind::StructElementAddrInst:
case ValueKind::RefElementAddrInst:
case ValueKind::RefTailAddrInst:
case ValueKind::ProjectBoxInst:
case ValueKind::TupleElementAddrInst:
case ValueKind::UncheckedTakeEnumDataAddrInst:
Expand All @@ -401,8 +385,7 @@ class Projection {
/// Returns true if this instruction projects from an object type into an
/// address subtype.
static bool isObjectToAddressProjection(SILValue V) {
return isa<RefElementAddrInst>(V) || isa<RefTailAddrInst>(V) ||
isa<ProjectBoxInst>(V);
return isa<RefElementAddrInst>(V) || isa<ProjectBoxInst>(V);
}

/// Given a specific SILType, return all first level projections if it is an
Expand All @@ -427,7 +410,6 @@ class Projection {
case ProjectionKind::Tuple:
case ProjectionKind::Index:
case ProjectionKind::Class:
case ProjectionKind::TailElems:
case ProjectionKind::Enum:
case ProjectionKind::Box:
return false;
Expand All @@ -446,7 +428,6 @@ class Projection {
case ProjectionKind::Tuple:
case ProjectionKind::Upcast:
case ProjectionKind::Box:
case ProjectionKind::TailElems:
return false;
}
}
Expand Down
31 changes: 3 additions & 28 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,26 +255,13 @@ class SILBuilder {
Var));
}

AllocRefInst *createAllocRef(SILLocation Loc, SILType ObjectType,
bool objc, bool canAllocOnStack) {
AllocRefInst *createAllocRef(SILLocation Loc, SILType elementType, bool objc,
bool canAllocOnStack) {
// AllocRefInsts expand to function calls and can therefore not be
// counted towards the function prologue.
assert(!Loc.isInPrologue());
return insert(AllocRefInst::create(getSILDebugLocation(Loc), F, ObjectType,
return insert(AllocRefInst::create(getSILDebugLocation(Loc), elementType, F,
objc, canAllocOnStack,
{}, {}, OpenedArchetypes));
}

AllocRefInst *createAllocRef(SILLocation Loc, SILType ObjectType,
bool canAllocOnStack,
ArrayRef<SILType> ElementTypes,
ArrayRef<SILValue> ElementCountOperands) {
// AllocRefInsts expand to function calls and can therefore not be
// counted towards the function prologue.
assert(!Loc.isInPrologue());
return insert(AllocRefInst::create(getSILDebugLocation(Loc),
F, ObjectType, false, canAllocOnStack,
ElementTypes, ElementCountOperands,
OpenedArchetypes));
}

Expand Down Expand Up @@ -911,12 +898,6 @@ class SILBuilder {
return createRefElementAddr(Loc, Operand, Field, ResultTy);
}

RefTailAddrInst *createRefTailAddr(SILLocation Loc, SILValue Ref,
SILType ResultTy) {
return insert(new (F.getModule()) RefTailAddrInst(getSILDebugLocation(Loc),
Ref, ResultTy));
}

ClassMethodInst *createClassMethod(SILLocation Loc, SILValue Operand,
SILDeclRef Member, SILType MethodTy,
bool Volatile = false) {
Expand Down Expand Up @@ -1262,12 +1243,6 @@ class SILBuilder {
Operand, Index));
}

TailAddrInst *createTailAddr(SILLocation Loc, SILValue Operand,
SILValue Count, SILType ResultTy) {
return insert(new (F.getModule()) TailAddrInst(getSILDebugLocation(Loc),
Operand, Count, ResultTy));
}

IndexRawPointerInst *createIndexRawPointer(SILLocation Loc, SILValue Operand,
SILValue Index) {
return insert(new (F.getModule()) IndexRawPointerInst(
Expand Down
Loading

0 comments on commit fbb3cf3

Please sign in to comment.