Skip to content

Commit 9c63d1e

Browse files
committed
Fix a bug with curried function emission and teach the mangler
to differentiate uncurried and curried function types. Swift SVN r1059
1 parent ac190ab commit 9c63d1e

File tree

5 files changed

+72
-45
lines changed

5 files changed

+72
-45
lines changed

lib/IRGen/GenFunc.cpp

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,20 @@ static unsigned getNaturalUncurryLevel(FuncDecl *func) {
9595
return count - 1;
9696
}
9797

98+
/// Given a function type, return the formal result type at the given
99+
/// uncurrying level. For 'a -> b -> c', this is 'b' at 0 and 'c' at 1.
100+
static Type getResultType(Type type, unsigned uncurryLevel) {
101+
do {
102+
type = type->castTo<FunctionType>()->Result;
103+
} while (uncurryLevel--);
104+
return type;
105+
}
106+
107+
const TypeInfo &IRGenFunction::getResultTypeInfo() const {
108+
Type resultType = getResultType(CurFuncExpr->getType(), CurUncurryLevel);
109+
return IGM.getFragileTypeInfo(resultType);
110+
}
111+
98112
namespace {
99113
/// A signature represents something which can actually be called.
100114
class Signature {
@@ -770,20 +784,17 @@ void IRGenFunction::emitPrologue() {
770784
CurFn->getBasicBlockList().push_back(ReturnBB);
771785

772786
// Copy over the arguments as an Explosion.
773-
Explosion args(ExplosionKind::Minimal);
787+
Explosion args(CurExplosionLevel);
774788
for (auto i = CurFn->arg_begin(), e = CurFn->arg_end(); i != e; ++i) {
775789
args.add(i);
776790
}
777791

778792
// Set up the return slot, stealing the first argument if necessary.
779793
{
780794
// Find the 'code' result type of this function.
781-
FunctionType *fnType = CurFuncExpr->getType()->castTo<FunctionType>();
782-
while (FunctionType *fnResult = dyn_cast<FunctionType>(fnType->Result))
783-
fnType = fnResult;
784-
const TypeInfo &resultType = IGM.getFragileTypeInfo(fnType->Result);
795+
const TypeInfo &resultType = getResultTypeInfo();
785796

786-
ExplosionSchema resultSchema(args.getKind());
797+
ExplosionSchema resultSchema(CurExplosionLevel);
787798
resultType.getExplosionSchema(resultSchema);
788799

789800
if (requiresAggregateResult(resultSchema)) {
@@ -865,26 +876,26 @@ void IRGenFunction::emitEpilogue() {
865876
Builder.SetInsertPoint(ReturnBB);
866877
}
867878

868-
FunctionType *FnTy = CurFuncExpr->getType()->castTo<FunctionType>();
869-
assert(FnTy && "emitting a declaration that's not a function?");
879+
const TypeInfo &resultType = getResultTypeInfo();
880+
ExplosionSchema resultSchema(CurExplosionLevel);
881+
resultType.getExplosionSchema(resultSchema);
870882

871-
const TypeInfo &resultType = IGM.getFragileTypeInfo(FnTy->Result);
872-
RValueSchema resultSchema = resultType.getSchema();
873-
if (resultSchema.isAggregate()) {
883+
if (requiresAggregateResult(resultSchema)) {
874884
assert(isa<llvm::Argument>(ReturnSlot.getAddress()));
875885
Builder.CreateRetVoid();
876-
} else if (resultSchema.isScalar(0)) {
886+
} else if (resultSchema.empty()) {
877887
assert(!ReturnSlot.isValid());
878888
Builder.CreateRetVoid();
879889
} else {
880-
RValue RV = resultType.load(*this, ReturnSlot);
881-
if (RV.isScalar(1)) {
882-
Builder.CreateRet(RV.getScalars()[0]);
890+
Explosion result(CurExplosionLevel);
891+
resultType.loadExplosion(*this, ReturnSlot, result);
892+
if (result.size() == 1) {
893+
Builder.CreateRet(result.claimNext());
883894
} else {
884-
llvm::Value *Result = llvm::UndefValue::get(CurFn->getReturnType());
885-
for (unsigned I = 0, E = RV.getScalars().size(); I != E; ++I)
886-
Result = Builder.CreateInsertValue(Result, RV.getScalars()[I], I);
887-
Builder.CreateRet(Result);
895+
llvm::Value *resultAgg = llvm::UndefValue::get(CurFn->getReturnType());
896+
for (unsigned i = 0, e = result.size(); i != e; ++i)
897+
resultAgg = Builder.CreateInsertValue(resultAgg, result.claimNext(), i);
898+
Builder.CreateRet(resultAgg);
888899
}
889900
}
890901
}
@@ -896,12 +907,15 @@ void IRGenModule::emitGlobalFunction(FuncDecl *func) {
896907

897908
// FIXME: variant currying levels!
898909
// FIXME: also emit entrypoints with maximal explosion when all types are known!
910+
unsigned uncurryLevel = getNaturalUncurryLevel(func);
911+
ExplosionKind explosionLevel = ExplosionKind::Minimal;
899912

900-
llvm::Function *addr = getAddrOfGlobalFunction(func, ExplosionKind::Minimal,
901-
getNaturalUncurryLevel(func));
913+
llvm::Function *addr =
914+
getAddrOfGlobalFunction(func, explosionLevel, uncurryLevel);
902915

903916
FuncExpr *funcExpr = cast<FuncExpr>(func->getInit());
904-
IRGenFunction(*this, funcExpr, addr).emitFunctionTopLevel(funcExpr->getBody());
917+
IRGenFunction(*this, funcExpr, explosionLevel, uncurryLevel, addr)
918+
.emitFunctionTopLevel(funcExpr->getBody());
905919
}
906920

907921
void IRGenFunction::emitFunctionTopLevel(BraceStmt *S) {

lib/IRGen/GenGlobal.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ void IRGenModule::emitTranslationUnit(TranslationUnit *tunit) {
6666
nullptr, tunit);
6767

6868
llvm::Function *fn = createGlobalInitFunction(*this, tunit);
69-
IRGenFunction(*this, &func, fn).emitGlobalTopLevel(tunit->Body);
69+
IRGenFunction(*this, &func, ExplosionKind::Minimal, /*uncurry*/ 0, fn)
70+
.emitGlobalTopLevel(tunit->Body);
7071

7172
// Not all translation units need a global initialization function.
7273
if (isTrivialGlobalInit(fn)) {

lib/IRGen/IRGenFunction.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@
2525
using namespace swift;
2626
using namespace irgen;
2727

28-
IRGenFunction::IRGenFunction(IRGenModule &IGM, FuncExpr *FE, llvm::Function *Fn)
29-
: IGM(IGM), Builder(IGM.getLLVMContext()), CurFuncExpr(FE), CurFn(Fn) {
28+
IRGenFunction::IRGenFunction(IRGenModule &IGM, FuncExpr *FE,
29+
ExplosionKind explosionLevel,
30+
unsigned uncurryLevel, llvm::Function *Fn)
31+
: IGM(IGM), Builder(IGM.getLLVMContext()), CurFuncExpr(FE), CurFn(Fn),
32+
CurExplosionLevel(explosionLevel), CurUncurryLevel(uncurryLevel) {
3033
emitPrologue();
3134
}
3235

lib/IRGen/IRGenFunction.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ namespace swift {
5353
namespace irgen {
5454
class Condition;
5555
class Explosion;
56+
enum class ExplosionKind : unsigned;
5657
class IRGenModule;
5758
class JumpDest;
5859
class LValue;
@@ -68,8 +69,11 @@ class IRGenFunction {
6869

6970
FuncExpr *CurFuncExpr;
7071
llvm::Function *CurFn;
72+
ExplosionKind CurExplosionLevel;
73+
unsigned CurUncurryLevel;
7174

72-
IRGenFunction(IRGenModule &IGM, FuncExpr *FE, llvm::Function *Fn);
75+
IRGenFunction(IRGenModule &IGM, FuncExpr *FE, ExplosionKind explosion,
76+
unsigned uncurryLevel, llvm::Function *fn);
7377
~IRGenFunction();
7478

7579
void unimplemented(SourceLoc Loc, StringRef Message);
@@ -88,6 +92,7 @@ class IRGenFunction {
8892
Address ReturnSlot;
8993
llvm::BasicBlock *ReturnBB;
9094
JumpDest getReturnDest();
95+
const TypeInfo &getResultTypeInfo() const;
9196

9297
//--- Helper methods -----------------------------------------------------------
9398
public:

lib/IRGen/Mangle.cpp

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include "IRGenModule.h"
2626
#include "Linking.h"
27+
#include "IRGen.h"
2728

2829
using namespace swift;
2930
using namespace irgen;
@@ -58,7 +59,7 @@ namespace {
5859
public:
5960
Mangler(raw_ostream &buffer) : Buffer(buffer) {}
6061
void mangleDeclName(NamedDecl *decl);
61-
void mangleType(Type type);
62+
void mangleType(Type type, ExplosionKind kind, unsigned uncurryingLevel);
6263

6364
private:
6465
void mangleDeclContext(DeclContext *ctx);
@@ -151,7 +152,8 @@ void Mangler::mangleDeclContext(DeclContext *ctx) {
151152

152153
case DeclContextKind::ExtensionDecl:
153154
// Mandle the extension as the original type.
154-
mangleType(cast<ExtensionDecl>(ctx)->getExtendedType());
155+
mangleType(cast<ExtensionDecl>(ctx)->getExtendedType(),
156+
ExplosionKind::Minimal, 0);
155157
return;
156158

157159
case DeclContextKind::FuncExpr:
@@ -174,7 +176,8 @@ void Mangler::mangleDeclName(NamedDecl *decl) {
174176
}
175177

176178
/// Mangle a type into the buffer.
177-
void Mangler::mangleType(Type type) {
179+
void Mangler::mangleType(Type type, ExplosionKind explosion,
180+
unsigned uncurryLevel) {
178181
TypeBase *base = type.getPointer();
179182

180183
switch (base->Kind) {
@@ -197,33 +200,32 @@ void Mangler::mangleType(Type type) {
197200
case BuiltinFloatType::IEEE64: Buffer << "f64"; return;
198201
case BuiltinFloatType::IEEE80: Buffer << "f80"; return;
199202
case BuiltinFloatType::IEEE128: Buffer << "f128"; return;
200-
case BuiltinFloatType::PPC128: assert(0 && "Unimplemented");
203+
case BuiltinFloatType::PPC128: llvm_unreachable("ppc128 not supported");
201204
}
202-
assert(0 && "Unreachable");
205+
llvm_unreachable("bad floating-point kind");
203206
case TypeKind::BuiltinInteger:
204207
Buffer << "i" << cast<BuiltinIntegerType>(type)->getBitWidth();
205208
return;
206209

207210
case TypeKind::NameAlias:
208-
return mangleType(cast<NameAliasType>(base)->TheDecl->getUnderlyingType());
211+
return mangleType(cast<NameAliasType>(base)->TheDecl->getUnderlyingType(),
212+
explosion, uncurryLevel);
209213
case TypeKind::DottedName:
210-
return mangleType(cast<DottedNameType>(base)->getMappedType());
214+
return mangleType(cast<DottedNameType>(base)->getMappedType(),
215+
explosion, uncurryLevel);
211216
case TypeKind::Paren:
212-
return mangleType(cast<ParenType>(base)->getUnderlyingType());
217+
return mangleType(cast<ParenType>(base)->getUnderlyingType(),
218+
explosion, uncurryLevel);
213219

214220
case TypeKind::Tuple: {
215221
TupleType *tuple = cast<TupleType>(base);
216-
// Look through simple parentheses.
217-
if (tuple->Fields.size() == 1 && tuple->Fields[0].Name.empty())
218-
return mangleType(tuple->Fields[0].Ty);
219-
220222
// type ::= 'T' tuple-field+ '_'
221223
// tuple-field ::= identifier? type
222224
Buffer << 'T';
223225
for (auto &field : tuple->Fields) {
224226
if (!field.Name.empty())
225227
mangleIdentifier(field.Name);
226-
mangleType(field.Ty);
228+
mangleType(field.Ty, explosion, 0);
227229
}
228230
Buffer << '_';
229231
return;
@@ -244,11 +246,13 @@ void Mangler::mangleType(Type type) {
244246
}
245247

246248
case TypeKind::Function: {
247-
// type ::= 'F' type type
249+
// type ::= 'F' type type (curried)
250+
// type ::= 'f' type type (uncurried)
248251
FunctionType *fn = cast<FunctionType>(base);
249-
Buffer << 'F';
250-
mangleType(fn->Input);
251-
mangleType(fn->Result);
252+
Buffer << (uncurryLevel > 0 ? 'f' : 'F');
253+
mangleType(fn->Input, explosion, 0);
254+
mangleType(fn->Result, explosion,
255+
(uncurryLevel > 0 ? uncurryLevel - 1 : 0));
252256
return;
253257
}
254258

@@ -257,7 +261,7 @@ void Mangler::mangleType(Type type) {
257261
ArrayType *array = cast<ArrayType>(base);
258262
Buffer << 'A';
259263
Buffer << array->Size;
260-
mangleType(array->Base);
264+
mangleType(array->Base, ExplosionKind::Minimal, 0);
261265
return;
262266
};
263267

@@ -304,7 +308,7 @@ void LinkEntity::mangle(raw_ostream &buffer) const {
304308
// moment they can *all* be overloaded.
305309
if (ValueDecl *valueDecl = dyn_cast<ValueDecl>(TheDecl))
306310
if (!isa<TypeAliasDecl>(TheDecl))
307-
mangler.mangleType(valueDecl->getType());
311+
mangler.mangleType(valueDecl->getType(), Explosion, UncurryLevel);
308312

309313
// TODO: mangle generics information here.
310314
}

0 commit comments

Comments
 (0)