move Instruction/BasicBlock/BBArgument files to have SIL prefixes.

Swift SVN r4591
This commit is contained in:
Chris Lattner
2013-04-03 18:43:54 +00:00
parent 65cd2b2d25
commit 1beebda868
14 changed files with 16 additions and 16 deletions

639
lib/SIL/SILInstruction.cpp Normal file
View File

@@ -0,0 +1,639 @@
//===--- Instruction.cpp - Instructions for SIL code ----------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the high-level Instruction classes used for Swift SIL code.
//
//===----------------------------------------------------------------------===//
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/SILVisitor.h"
#include "swift/AST/AST.h"
#include "swift/SIL/SILFunction.h"
#include "llvm/Support/ErrorHandling.h"
using namespace swift;
//===----------------------------------------------------------------------===//
// ilist_traits<Instruction> Implementation
//===----------------------------------------------------------------------===//
// The trait object is embedded into a basic block. Use dirty hacks to
// reconstruct the BB from the 'this' pointer of the trait.
BasicBlock *llvm::ilist_traits<Instruction>::getContainingBlock() {
typedef iplist<Instruction> BasicBlock::*Sublist;
size_t Offset(size_t(&((BasicBlock*)0->*BasicBlock::getSublistAccess())));
iplist<Instruction>* Anchor(static_cast<iplist<Instruction>*>(this));
return reinterpret_cast<BasicBlock*>(reinterpret_cast<char*>(Anchor)-Offset);
}
void llvm::ilist_traits<Instruction>::addNodeToList(Instruction *I) {
assert(I->ParentBB == 0 && "Already in a list!");
I->ParentBB = getContainingBlock();
}
void llvm::ilist_traits<Instruction>::removeNodeFromList(Instruction *I) {
// When an instruction is removed from a BB, clear the parent pointer.
assert(I->ParentBB && "Not in a list!");
I->ParentBB = 0;
}
void llvm::ilist_traits<Instruction>::
transferNodesFromList(llvm::ilist_traits<Instruction> &L2,
llvm::ilist_iterator<Instruction> first,
llvm::ilist_iterator<Instruction> last) {
// If transfering instructions within the same basic block, no reason to
// update their parent pointers.
BasicBlock *ThisParent = getContainingBlock();
if (ThisParent == L2.getContainingBlock()) return;
// Update the parent fields in the instructions.
for (; first != last; ++first)
first->ParentBB = ThisParent;
}
//===----------------------------------------------------------------------===//
// Instruction Implementation
//===----------------------------------------------------------------------===//
/// removeFromParent - This method unlinks 'this' from the containing basic
/// block, but does not delete it.
///
void Instruction::removeFromParent() {
getParent()->getInsts().remove(this);
}
/// eraseFromParent - This method unlinks 'this' from the containing basic
/// block and deletes it.
///
void Instruction::eraseFromParent() {
getParent()->getInsts().erase(this);
}
namespace {
class InstructionDestroyer : public SILVisitor<InstructionDestroyer> {
public:
#define VALUE(CLASS, PARENT) void visit##CLASS(CLASS *I) { I->~CLASS(); }
#include "swift/SIL/SILNodes.def"
};
} // end anonymous namespace
void Instruction::destroy(Instruction *I) {
InstructionDestroyer().visit(I);
}
//===----------------------------------------------------------------------===//
// Instruction Subclasses
//===----------------------------------------------------------------------===//
AllocVarInst::AllocVarInst(SILLocation loc, AllocKind allocKind,
SILType elementType,
SILFunction &F)
: AllocInst(ValueKind::AllocVarInst, loc,
elementType.getAddressType(),
allocKind) {
}
/// getDecl - Return the underlying variable declaration associated with this
/// allocation, or null if this is a temporary allocation.
VarDecl *AllocVarInst::getDecl() const {
if (Decl *d = getLoc().dyn_cast<Decl*>()) {
return dyn_cast<VarDecl>(d);
} else {
return nullptr;
}
}
AllocRefInst::AllocRefInst(SILLocation loc, AllocKind allocKind,
SILType elementType,
SILFunction &F)
: AllocInst(ValueKind::AllocRefInst, loc,
elementType,
allocKind) {
}
/// getElementType - Get the type of the allocated memory (as opposed to the
/// type of the instruction itself, which will be an address type).
Type AllocVarInst::getElementType() const {
return getType().getSwiftRValueType();
}
// Allocations always return two results: Builtin.ObjectPointer & LValue[EltTy]
static SILTypeList *getAllocType(SILType EltTy, SILFunction &F) {
ASTContext &Ctx = EltTy.getASTContext();
SILType ResTys[] = {
SILType::getObjectPointerType(Ctx),
EltTy.getAddressType()
};
return F.getModule().getSILTypeList(ResTys);
}
AllocBoxInst::AllocBoxInst(SILLocation Loc, SILType ElementType, SILFunction &F)
: Instruction(ValueKind::AllocBoxInst, Loc, getAllocType(ElementType, F)) {
}
Type AllocBoxInst::getElementType() const {
return getType(1).getSwiftRValueType();
}
AllocArrayInst::AllocArrayInst(SILLocation Loc, SILType ElementType,
Value NumElements, SILFunction &F)
: Instruction(ValueKind::AllocArrayInst, Loc, getAllocType(ElementType, F)),
Operands(this, NumElements) {
}
Type AllocArrayInst::getElementType() const {
return getType(1).getSwiftRValueType();
}
FunctionInst::FunctionInst(ValueKind kind,
SILLocation Loc, SILType Ty, Value Callee,
ArrayRef<Value> Args)
: Instruction(kind, Loc, Ty), Operands(this, Args, Callee) {
}
template<typename DERIVED, typename...T>
DERIVED *FunctionInst::create(SILFunction &F, ArrayRef<Value> Args,
T &&...ConstructorArgs) {
// The way we store operands requires this.
static_assert(sizeof(DERIVED) == sizeof(FunctionInst),
"can't have extra storage in a FunctionInst subclass");
void *Buffer = F.allocate(sizeof(DERIVED) +
decltype(Operands)::getExtraSize(Args.size()),
alignof(DERIVED));
return ::new(Buffer) DERIVED(::std::forward<T>(ConstructorArgs)...);
}
ApplyInst::ApplyInst(SILLocation Loc, Value Callee,
SILType Result, ArrayRef<Value> Args)
: FunctionInst(ValueKind::ApplyInst, Loc, Result,
Callee, Args) {
}
ApplyInst *ApplyInst::create(SILLocation Loc, Value Callee,
SILType Result, ArrayRef<Value> Args,
SILFunction &F) {
return FunctionInst::create<ApplyInst>(F, Args,
Loc, Callee, Result, Args);
}
PartialApplyInst::PartialApplyInst(SILLocation Loc, Value Callee,
ArrayRef<Value> Args, SILType ClosureType)
// FIXME: the callee should have a lowered SIL function type, and PartialApplyInst
// should derive the type of its result by partially applying the callee's type.
: FunctionInst(ValueKind::PartialApplyInst, Loc,
ClosureType,
Callee, Args) {
}
PartialApplyInst *PartialApplyInst::create(SILLocation Loc, Value Callee,
ArrayRef<Value> Args,
SILType ClosureType,
SILFunction &F) {
return FunctionInst::create<PartialApplyInst>(F, Args, Loc, Callee,
Args, ClosureType);
}
ConstantRefInst::ConstantRefInst(SILLocation Loc, SILConstant C, SILType Ty)
: Instruction(ValueKind::ConstantRefInst, Loc, Ty),
Constant(C) {
}
SILConstant ConstantRefInst::getConstant() const {
return Constant;
}
IntegerLiteralInst::IntegerLiteralInst(IntegerLiteralExpr *E)
: Instruction(ValueKind::IntegerLiteralInst, E,
// Builtin integer types are always valid SIL types.
SILType::getPreLoweredType(E->getType()->getCanonicalType(),
/*address=*/false, /*loadable=*/true)) {
}
IntegerLiteralInst::IntegerLiteralInst(CharacterLiteralExpr *E)
: Instruction(ValueKind::IntegerLiteralInst, E,
// Builtin integer types are always valid SIL types.
SILType::getPreLoweredType(E->getType()->getCanonicalType(),
/*address=*/false, /*loadable=*/true)) {
}
Expr *IntegerLiteralInst::getExpr() const {
return getLocExpr<Expr>();
}
/// getValue - Return the APInt for the underlying integer literal.
APInt IntegerLiteralInst::getValue() const {
auto expr = getExpr();
if (auto intExpr = dyn_cast<IntegerLiteralExpr>(expr)) {
return intExpr->getValue();
} else if (auto charExpr = dyn_cast<CharacterLiteralExpr>(expr)) {
return APInt(32, charExpr->getValue());
}
llvm_unreachable("int_literal instruction associated with unexpected "
"ast node!");
}
FloatLiteralInst::FloatLiteralInst(FloatLiteralExpr *E)
: Instruction(ValueKind::FloatLiteralInst, E,
// Builtin floating-point types are always valid SIL types.
SILType::getPreLoweredType(E->getType()->getCanonicalType(),
/*address=*/false, /*loadable=*/true)) {
}
FloatLiteralExpr *FloatLiteralInst::getExpr() const {
return getLocExpr<FloatLiteralExpr>();
}
APFloat FloatLiteralInst::getValue() const {
return getExpr()->getValue();
}
StringLiteralInst::StringLiteralInst(StringLiteralExpr *E)
: Instruction(ValueKind::StringLiteralInst, E,
// The string literal tuple type is always a valid SIL type.
SILType::getPreLoweredType(E->getType()->getCanonicalType(),
/*address=*/false, /*loadable=*/true)) {
}
StringLiteralExpr *StringLiteralInst::getExpr() const {
return getLocExpr<StringLiteralExpr>();
}
StringRef StringLiteralInst::getValue() const {
return getExpr()->getValue();
}
LoadInst::LoadInst(SILLocation Loc, Value LValue)
: Instruction(ValueKind::LoadInst, Loc, LValue.getType().getObjectType()),
Operands(this, LValue) {
}
StoreInst::StoreInst(SILLocation Loc, Value Src, Value Dest)
: Instruction(ValueKind::StoreInst, Loc),
Operands(this, Src, Dest) {
}
CopyAddrInst::CopyAddrInst(SILLocation Loc, Value SrcLValue, Value DestLValue,
bool IsTakeOfSrc, bool IsInitializationOfDest)
: Instruction(ValueKind::CopyAddrInst, Loc),
IsTakeOfSrc(IsTakeOfSrc), IsInitializationOfDest(IsInitializationOfDest),
Operands(this, SrcLValue, DestLValue)
{
}
InitializeVarInst::InitializeVarInst(SILLocation Loc, Value Dest)
: Instruction(ValueKind::InitializeVarInst, Loc), Operands(this, Dest) {
}
SpecializeInst *SpecializeInst::create(SILLocation Loc, Value Operand,
ArrayRef<Substitution> Substitutions,
SILType DestTy, SILFunction &F) {
void *Buffer = F.allocate(
sizeof(SpecializeInst) + Substitutions.size() * sizeof(Substitution),
alignof(SpecializeInst));
return ::new(Buffer) SpecializeInst(Loc, Operand, Substitutions, DestTy);
}
SpecializeInst::SpecializeInst(SILLocation Loc, Value Operand,
ArrayRef<Substitution> Substitutions,
SILType DestTy)
: Instruction(ValueKind::SpecializeInst, Loc, DestTy),
Operands(this, Operand), NumSubstitutions(Substitutions.size())
{
memcpy(getSubstitutionsStorage(), Substitutions.data(),
Substitutions.size() * sizeof(Substitution));
}
ConversionInst::ConversionInst(ValueKind Kind,
SILLocation Loc, Value Operand, SILType Ty)
: Instruction(Kind, Loc, Ty), Operands(this, Operand) {
}
ConvertFunctionInst::ConvertFunctionInst(SILLocation Loc, Value Operand,
SILType Ty)
: ConversionInst(ValueKind::ConvertFunctionInst, Loc, Operand, Ty) {
}
CoerceInst::CoerceInst(SILLocation Loc, Value Operand, SILType Ty)
: ConversionInst(ValueKind::CoerceInst, Loc, Operand, Ty) {
}
UpcastInst::UpcastInst(SILLocation Loc, Value Operand, SILType Ty)
: ConversionInst(ValueKind::UpcastInst, Loc, Operand, Ty) {
}
DowncastInst::DowncastInst(SILLocation Loc, Value Operand, SILType Ty)
: ConversionInst(ValueKind::DowncastInst, Loc, Operand, Ty) {
}
AddressToPointerInst::AddressToPointerInst(SILLocation Loc, Value Operand,
SILType Ty)
: ConversionInst(ValueKind::AddressToPointerInst, Loc, Operand, Ty) {
}
ThinToThickFunctionInst::ThinToThickFunctionInst(SILLocation Loc, Value Operand,
SILType Ty)
: ConversionInst(ValueKind::ThinToThickFunctionInst, Loc, Operand, Ty) {
}
ArchetypeToSuperInst::ArchetypeToSuperInst(SILLocation Loc,
Value Operand, SILType Ty)
: ConversionInst(ValueKind::ArchetypeToSuperInst, Loc, Operand, Ty) {
}
SuperToArchetypeInst::SuperToArchetypeInst(SILLocation Loc,
Value SrcBase,
Value DestArchetypeAddress)
: Instruction(ValueKind::SuperToArchetypeInst, Loc),
Operands(this, SrcBase, DestArchetypeAddress) {
}
TupleInst *TupleInst::createImpl(SILLocation Loc, SILType Ty,
ArrayRef<Value> Elements, SILFunction &F) {
void *Buffer = F.allocate(sizeof(TupleInst) +
decltype(Operands)::getExtraSize(Elements.size()),
alignof(TupleInst));
return ::new(Buffer) TupleInst(Loc, Ty, Elements);
}
TupleInst::TupleInst(SILLocation Loc, SILType Ty, ArrayRef<Value> Elems)
: Instruction(ValueKind::TupleInst, Loc, Ty), Operands(this, Elems) {
}
MetatypeInst::MetatypeInst(SILLocation Loc, SILType Metatype)
: Instruction(ValueKind::MetatypeInst, Loc, Metatype) {}
ClassMetatypeInst::ClassMetatypeInst(SILLocation Loc, SILType Metatype,
Value Base)
: Instruction(ValueKind::ClassMetatypeInst, Loc, Metatype),
Operands(this, Base) {}
ArchetypeMetatypeInst::ArchetypeMetatypeInst(SILLocation Loc, SILType Metatype,
Value Base)
: Instruction(ValueKind::ArchetypeMetatypeInst, Loc, Metatype),
Operands(this, Base) {}
ProtocolMetatypeInst::ProtocolMetatypeInst(SILLocation Loc, SILType Metatype,
Value Base)
: Instruction(ValueKind::ProtocolMetatypeInst, Loc, Metatype),
Operands(this, Base) {}
ModuleInst::ModuleInst(SILLocation Loc, SILType ModuleType)
: Instruction(ValueKind::ModuleInst, Loc, ModuleType) {}
AssociatedMetatypeInst::AssociatedMetatypeInst(SILLocation Loc,
Value MetatypeSrc,
SILType MetatypeDest)
: Instruction(ValueKind::AssociatedMetatypeInst, Loc, MetatypeDest),
Operands(this, MetatypeSrc) {}
ExtractInst::ExtractInst(SILLocation Loc, Value Operand,
unsigned FieldNo, SILType ResultTy)
: Instruction(ValueKind::ExtractInst, Loc, ResultTy),
Operands(this, Operand), FieldNo(FieldNo) {
}
ElementAddrInst::ElementAddrInst(SILLocation Loc, Value Operand,
unsigned FieldNo, SILType ResultTy)
: Instruction(ValueKind::ElementAddrInst, Loc, ResultTy),
Operands(this, Operand), FieldNo(FieldNo) {
}
RefElementAddrInst::RefElementAddrInst(SILLocation Loc, Value Operand,
VarDecl *Field, SILType ResultTy)
: Instruction(ValueKind::RefElementAddrInst, Loc, ResultTy),
Operands(this, Operand), Field(Field) {
}
DynamicMethodInst::DynamicMethodInst(ValueKind Kind,
SILLocation Loc, Value Operand,
SILConstant Member,
SILType Ty,
SILFunction &F)
: Instruction(Kind, Loc, Ty),
Operands(this, Operand), Member(Member) {
}
ClassMethodInst::ClassMethodInst(SILLocation Loc, Value Operand,
SILConstant Member,
SILType Ty,
SILFunction &F)
: DynamicMethodInst(ValueKind::ClassMethodInst,
Loc, Operand, Member,
Ty, F) {
}
SuperMethodInst::SuperMethodInst(SILLocation Loc, Value Operand,
SILConstant Member,
SILType Ty,
SILFunction &F)
: DynamicMethodInst(ValueKind::SuperMethodInst,
Loc, Operand, Member,
Ty, F) {
}
ArchetypeMethodInst::ArchetypeMethodInst(SILLocation Loc, Value Operand,
SILConstant Member,
SILType Ty,
SILFunction &F)
: DynamicMethodInst(ValueKind::ArchetypeMethodInst,
Loc, Operand, Member,
Ty, F) {
}
ProtocolMethodInst::ProtocolMethodInst(SILLocation Loc, Value Operand,
SILConstant Member,
SILType Ty,
SILFunction &F)
: DynamicMethodInst(ValueKind::ProtocolMethodInst,
Loc, Operand, Member,
Ty, F) {
}
ProjectExistentialInst::ProjectExistentialInst(SILLocation Loc, Value Operand,
SILFunction &F)
: Instruction(ValueKind::ProjectExistentialInst, Loc,
SILType::getOpaquePointerType(F.getContext())),
Operands(this, Operand) {
}
InitExistentialInst::InitExistentialInst(SILLocation Loc,
Value Existential,
SILType ConcreteType,
ArrayRef<ProtocolConformance*> Conformances)
: Instruction(ValueKind::InitExistentialInst, Loc,
ConcreteType.getAddressType()),
Operands(this, Existential),
Conformances(Conformances) {
}
Type InitExistentialInst::getConcreteType() const {
return getType(0).getSwiftRValueType();
}
UpcastExistentialInst::UpcastExistentialInst(SILLocation Loc,
Value SrcExistential,
Value DestExistential,
bool isTakeOfSrc,
ArrayRef<ProtocolConformance*> Conformances)
: Instruction(ValueKind::UpcastExistentialInst, Loc),
IsTakeOfSrc(isTakeOfSrc),
Operands(this, SrcExistential, DestExistential),
Conformances(Conformances)
{
}
DeinitExistentialInst::DeinitExistentialInst(SILLocation Loc,
Value Existential)
: Instruction(ValueKind::DeinitExistentialInst, Loc,
SILType::getEmptyTupleType(Existential.getType().getASTContext())),
Operands(this, Existential) {
}
RetainInst::RetainInst(SILLocation Loc, Value Operand)
: Instruction(ValueKind::RetainInst, Loc, Operand.getType()),
Operands(this, Operand) {
}
ReleaseInst::ReleaseInst(SILLocation Loc, Value Operand)
: Instruction(ValueKind::ReleaseInst, Loc), Operands(this, Operand) {
}
DeallocVarInst::DeallocVarInst(SILLocation loc, AllocKind allocKind,
Value operand)
: Instruction(ValueKind::DeallocVarInst, loc), allocKind(allocKind),
Operands(this, operand) {
}
DeallocRefInst::DeallocRefInst(SILLocation loc, Value operand)
: Instruction(ValueKind::DeallocRefInst, loc),
Operands(this, operand) {
}
DestroyAddrInst::DestroyAddrInst(SILLocation Loc, Value Operand)
: Instruction(ValueKind::DestroyAddrInst, Loc), Operands(this, Operand) {
}
//===----------------------------------------------------------------------===//
// SIL-only instructions that don't have an AST analog
//===----------------------------------------------------------------------===//
IndexAddrInst::IndexAddrInst(SILLocation Loc, Value Operand, unsigned Index)
: Instruction(ValueKind::IndexAddrInst, Loc, Operand.getType()),
Operands(this, Operand), Index(Index) {
}
IntegerValueInst::IntegerValueInst(uint64_t Val, SILType Ty)
: Instruction(ValueKind::IntegerValueInst, SILLocation(), Ty), Val(Val) {}
//===----------------------------------------------------------------------===//
// Instructions representing terminators
//===----------------------------------------------------------------------===//
TermInst::SuccessorListTy TermInst::getSuccessors() {
assert(isa<TermInst>(this) && "Only TermInsts are allowed");
if (auto I = dyn_cast<UnreachableInst>(this))
return I->getSuccessors();
if (auto I = dyn_cast<ReturnInst>(this))
return I->getSuccessors();
if (auto I = dyn_cast<CondBranchInst>(this))
return I->getSuccessors();
return cast<BranchInst>(this)->getSuccessors();
}
UnreachableInst::UnreachableInst(SILFunction &F)
: TermInst(ValueKind::UnreachableInst, SILLocation(),
SILType::getEmptyTupleType(F.getContext())) {
}
ReturnInst::ReturnInst(SILLocation Loc, Value ReturnValue)
: TermInst(ValueKind::ReturnInst, Loc),
Operands(this, ReturnValue) {
}
BranchInst::BranchInst(SILLocation Loc,
BasicBlock *DestBB,
ArrayRef<Value> Args)
: TermInst(ValueKind::BranchInst, Loc),
DestBB(this, DestBB), Operands(this, Args)
{
assert(Args.size() == DestBB->bbarg_size() &&
"branch argument count does not match target bb");
}
BranchInst *BranchInst::create(SILLocation Loc,
BasicBlock *DestBB,
SILFunction &F) {
return create(Loc, DestBB, {}, F);
}
BranchInst *BranchInst::create(SILLocation Loc,
BasicBlock *DestBB, ArrayRef<Value> Args,
SILFunction &F) {
void *Buffer = F.allocate(sizeof(BranchInst) +
decltype(Operands)::getExtraSize(Args.size()),
alignof(BranchInst));
return ::new (Buffer) BranchInst(Loc, DestBB, Args);
}
CondBranchInst::CondBranchInst(SILLocation Loc, Value Condition,
BasicBlock *TrueBB, BasicBlock *FalseBB,
ArrayRef<Value> Args)
: TermInst(ValueKind::CondBranchInst, Loc),
DestBBs{{this, TrueBB}, {this, FalseBB}},
Operands(this, Args, Condition)
{
}
CondBranchInst *CondBranchInst::create(SILLocation Loc, Value Condition,
BasicBlock *TrueBB, BasicBlock *FalseBB,
SILFunction &F) {
return create(Loc, Condition, TrueBB, {}, FalseBB, {}, F);
}
CondBranchInst *CondBranchInst::create(SILLocation Loc, Value Condition,
BasicBlock *TrueBB, ArrayRef<Value> TrueArgs,
BasicBlock *FalseBB, ArrayRef<Value> FalseArgs,
SILFunction &F) {
assert(TrueArgs.size() == TrueBB->bbarg_size() &&
FalseArgs.size() == FalseBB->bbarg_size() &&
"branch argument counts do not match target bbs");
SmallVector<Value, 4> Args;
Args.append(TrueArgs.begin(), TrueArgs.end());
Args.append(FalseArgs.begin(), FalseArgs.end());
void *Buffer = F.allocate(sizeof(CondBranchInst) +
decltype(Operands)::getExtraSize(Args.size()),
alignof(CondBranchInst));
return ::new (Buffer) CondBranchInst(Loc, Condition, TrueBB, FalseBB, Args);
}
OperandValueArrayRef CondBranchInst::getTrueArgs() const {
return Operands.getValues().slice(1, getTrueBB()->bbarg_size());
}
OperandValueArrayRef CondBranchInst::getFalseArgs() const {
return Operands.getValues().slice(1 + getTrueBB()->bbarg_size(),
getFalseBB()->bbarg_size());
}