mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
remove CallSite and emitRValueForFunction
Swift SVN r4795
This commit is contained in:
@@ -22,7 +22,6 @@
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
|
||||
#include "Address.h"
|
||||
#include "CallEmission.h"
|
||||
#include "Explosion.h"
|
||||
#include "GenHeap.h"
|
||||
#include "GenType.h"
|
||||
|
||||
@@ -89,7 +89,6 @@ static void emitDeclRef(IRGenFunction &IGF, ValueDecl *D, Type Ty, SourceLoc Loc
|
||||
case DeclKind::Var:
|
||||
|
||||
case DeclKind::Func:
|
||||
return emitRValueForFunction(IGF, cast<FuncDecl>(D), explosion);
|
||||
|
||||
case DeclKind::OneOfElement:
|
||||
case DeclKind::Subscript:
|
||||
|
||||
@@ -786,142 +786,6 @@ static Callee emitIndirectCallee(IRGenFunction &IGF,
|
||||
fnPtr, dataPtr);
|
||||
}
|
||||
|
||||
/// Emit a reference to a function, using the best parameters possible
|
||||
/// up to given limits.
|
||||
static Callee emitDirectCallee(IRGenFunction &IGF, ValueDecl *val,
|
||||
CanType substResultType,
|
||||
ArrayRef<Substitution> subs,
|
||||
ExplosionKind bestExplosion,
|
||||
unsigned bestUncurry) {
|
||||
llvm::AttributeSet unusedAttrs;
|
||||
|
||||
if (bestUncurry != 0 || bestExplosion != ExplosionKind::Minimal) {
|
||||
auto absCallee = AbstractCallee::forDirectFunction(IGF, val);
|
||||
bestUncurry = std::min(bestUncurry, absCallee.getMaxUncurryLevel());
|
||||
bestExplosion = absCallee.getBestExplosionLevel();
|
||||
}
|
||||
|
||||
if (ConstructorDecl *ctor = dyn_cast<ConstructorDecl>(val)) {
|
||||
llvm::Constant *fnPtr;
|
||||
if (bestUncurry != 1) {
|
||||
IGF.unimplemented(val->getLoc(), "uncurried reference to constructor");
|
||||
fnPtr = llvm::UndefValue::get(
|
||||
IGF.IGM.getFunctionType(AbstractCC::Freestanding,
|
||||
val->getType()->getCanonicalType(),
|
||||
bestExplosion, bestUncurry,
|
||||
ExtraData::None, unusedAttrs));
|
||||
} else {
|
||||
fnPtr = IGF.IGM.getAddrOfConstructor(ctor, ConstructorKind::Allocating,
|
||||
bestExplosion);
|
||||
}
|
||||
return Callee::forFreestandingFunction(AbstractCC::Freestanding,
|
||||
ctor->getType()->getCanonicalType(),
|
||||
substResultType, subs, fnPtr,
|
||||
bestExplosion, bestUncurry);
|
||||
}
|
||||
|
||||
if (OneOfElementDecl *oneofelt = dyn_cast<OneOfElementDecl>(val)) {
|
||||
llvm::Constant *fnPtr;
|
||||
if (bestUncurry != (oneofelt->hasArgumentType() ? 1 : 0)) {
|
||||
IGF.unimplemented(val->getLoc(), "uncurried reference to oneof element");
|
||||
fnPtr = llvm::UndefValue::get(
|
||||
IGF.IGM.getFunctionType(AbstractCC::Freestanding,
|
||||
val->getType()->getCanonicalType(),
|
||||
bestExplosion, bestUncurry,
|
||||
ExtraData::None,
|
||||
unusedAttrs));
|
||||
} else {
|
||||
fnPtr = IGF.IGM.getAddrOfInjectionFunction(oneofelt);
|
||||
}
|
||||
return Callee::forFreestandingFunction(AbstractCC::Freestanding,
|
||||
oneofelt->getType()->getCanonicalType(),
|
||||
substResultType, subs, fnPtr,
|
||||
bestExplosion, bestUncurry);
|
||||
}
|
||||
|
||||
FuncDecl *fn = cast<FuncDecl>(val);
|
||||
FunctionRef fnRef = FunctionRef(fn, bestExplosion, bestUncurry);
|
||||
if (!fn->getDeclContext()->isLocalContext()) {
|
||||
llvm::Constant *fnPtr = IGF.IGM.getAddrOfFunction(fnRef, ExtraData::None);
|
||||
if (fn->isInstanceMember()) {
|
||||
return Callee::forMethod(fn->getType()->getCanonicalType(),
|
||||
substResultType, subs, fnPtr,
|
||||
bestExplosion, bestUncurry);
|
||||
} else {
|
||||
return Callee::forFreestandingFunction(getAbstractCC(fn),
|
||||
fn->getType()->getCanonicalType(),
|
||||
substResultType, subs, fnPtr,
|
||||
bestExplosion, bestUncurry);
|
||||
}
|
||||
}
|
||||
|
||||
auto fnPtr = IGF.getAddrOfLocalFunction(fnRef);
|
||||
Explosion e(ExplosionKind::Maximal);
|
||||
IGF.emitRetain(IGF.getLocalFuncData(fn), e);
|
||||
ManagedValue data = e.claimNext();
|
||||
if (isa<llvm::ConstantPointerNull>(data.getValue()))
|
||||
data = ManagedValue(nullptr);
|
||||
return Callee::forKnownFunction(AbstractCC::Freestanding,
|
||||
fn->getType()->getCanonicalType(),
|
||||
substResultType, subs, fnPtr, data,
|
||||
bestExplosion, bestUncurry);
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
/// A single call site, with argument expression and the type of
|
||||
/// function being applied.
|
||||
struct CallSite {
|
||||
CallSite(ApplyExpr *apply)
|
||||
: Apply(apply), FnType(apply->getFn()->getType()->getCanonicalType()) {}
|
||||
|
||||
ApplyExpr *Apply;
|
||||
|
||||
/// The function type that we're actually calling. This is
|
||||
/// "un-substituted" if necessary.
|
||||
CanType FnType;
|
||||
|
||||
Expr *getArg() const { return Apply->getArg(); }
|
||||
CanType getSubstResultType() const {
|
||||
return Apply->getType()->getCanonicalType();
|
||||
}
|
||||
|
||||
void emit(IRGenFunction &IGF, ArrayRef<Substitution> subs,
|
||||
Explosion &out) const {
|
||||
assert(!subs.empty() || !FnType->is<PolymorphicFunctionType>());
|
||||
|
||||
// If we have substitutions, then (1) it's possible for this to
|
||||
// be a polymorphic function type that we need to expand and
|
||||
// (2) we might need to evaluate the r-value differently.
|
||||
if (!subs.empty()) {
|
||||
auto fnType = cast<AnyFunctionType>(FnType);
|
||||
IGF.emitRValueAsUnsubstituted(getArg(), CanType(fnType->getInput()),
|
||||
subs, out);
|
||||
if (auto polyFn = dyn_cast<PolymorphicFunctionType>(fnType)) {
|
||||
auto substInputType = getArg()->getType()->getCanonicalType();
|
||||
emitPolymorphicArguments(IGF, polyFn, substInputType, subs, out);
|
||||
}
|
||||
} else {
|
||||
IGF.emitRValue(getArg(), out);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Emit a reference to the given function as a generic function pointer.
|
||||
void irgen::emitRValueForFunction(IRGenFunction &IGF, FuncDecl *fn,
|
||||
Explosion &explosion) {
|
||||
// Function pointers are always fully curried and use ExplosionKind::Minimal.
|
||||
CanType fnType = fn->getType()->getCanonicalType();
|
||||
CanType resultType = CanType(cast<AnyFunctionType>(fnType)->getResult());
|
||||
Callee callee = emitDirectCallee(IGF, fn, resultType,
|
||||
ArrayRef<Substitution>(),
|
||||
ExplosionKind::Minimal, 0);
|
||||
assert(callee.getExplosionLevel() == ExplosionKind::Minimal);
|
||||
assert(callee.getUncurryLevel() == 0);
|
||||
explosion.addUnmanaged(callee.getOpaqueFunctionPointer(IGF));
|
||||
explosion.add(callee.getDataPointer(IGF));
|
||||
}
|
||||
|
||||
static void extractUnmanagedScalarResults(IRGenFunction &IGF,
|
||||
llvm::Value *call,
|
||||
|
||||
@@ -30,15 +30,9 @@ namespace swift {
|
||||
namespace irgen {
|
||||
class Address;
|
||||
class Alignment;
|
||||
class CallEmission;
|
||||
class Explosion;
|
||||
class IRGenFunction;
|
||||
class TypeInfo;
|
||||
|
||||
/// Emit an r-value reference to a function.
|
||||
void emitRValueForFunction(IRGenFunction &IGF, FuncDecl *Fn,
|
||||
Explosion &explosion);
|
||||
|
||||
/// Return the natural level at which to uncurry this function. This
|
||||
/// is the number of additional parameter clauses that are uncurried
|
||||
/// in the function body.
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "swift/AST/Types.h"
|
||||
#include "swift/Basic/Optional.h"
|
||||
#include "ASTVisitor.h"
|
||||
#include "CallEmission.h"
|
||||
#include "GenClass.h"
|
||||
#include "GenInit.h"
|
||||
#include "GenPoly.h"
|
||||
|
||||
Reference in New Issue
Block a user