IRGen for varargs tuples.

Swift SVN r1883
This commit is contained in:
Eli Friedman
2012-05-17 03:22:49 +00:00
parent 5e206bc10f
commit 1341f19da8
3 changed files with 78 additions and 3 deletions

View File

@@ -29,6 +29,8 @@
#include "llvm/Target/TargetData.h"
#include "ASTVisitor.h"
#include "GenArray.h"
#include "GenHeap.h"
#include "GenInit.h"
#include "GenSequential.h"
#include "GenType.h"
@@ -269,6 +271,63 @@ void swift::irgen::emitTupleShuffle(IRGenFunction &IGF, TupleShuffleExpr *E,
continue;
}
// If the shuffle index is -2, it is the beginning of the list of
// varargs inputs.
if (shuffleIndex == -2) {
auto shuffleIndexIteratorEnd = E->getElementMapping().end();
unsigned numElems = shuffleIndexIteratorEnd - shuffleIndexIterator;
llvm::Value *length = IGF.Builder.getInt64(numElems);
const TypeInfo &elementTI =
IGF.getFragileTypeInfo(outerField.getVarargBaseTy());
Expr *init = nullptr;
ArrayHeapLayout layout(IGF.IGM, elementTI);
// Allocate the array.
// FIXME: This includes an unnecessary memset.
// FIXME: It would be nice if we could eventually avoid heap-allocating
// this array.
Address begin;
ManagedValue alloc =
layout.emitAlloc(IGF, length, begin, init, "new-array");
// Perform the call which generates the slice value.
emitArrayInjectionCall(IGF, alloc, begin,
outerField.getType(),
E->getVarargsInjectionFunction(), length,
outerTupleExplosion);
// Emit all the elements into the allocated array.
unsigned curElem = 0;
while (shuffleIndexIterator != shuffleIndexIteratorEnd) {
int shuffleIndex = *shuffleIndexIterator++;
const TupleFieldInfo &innerField
= innerTupleType.getFields()[(unsigned) shuffleIndex];
Explosion varargTupleExplosion(ExplosionKind::Maximal);
llvm::Value *curElemVal = IGF.Builder.getInt64(curElem++);
llvm::Value *destValue = IGF.Builder.CreateGEP(begin.getAddress(),
curElemVal);
Address destAddr(destValue, begin.getAlignment());
// If we're loading from an l-value, project from that.
if (innerTupleAddr.isValid()) {
Address elementAddr = innerField.projectAddress(IGF, innerTupleAddr);
elementTI.initializeWithCopy(IGF, destAddr, elementAddr);
// Otherwise, project the r-value down.
} else {
// Get the range of elements and project those down.
auto fieldRange =
innerField.getProjectionRange(innerTupleExplosion.getKind());
varargTupleExplosion.add(
innerTupleExplosion.getRange(fieldRange.first, fieldRange.second));
elementTI.initialize(IGF, varargTupleExplosion, destAddr);
}
}
break;
}
// Otherwise, we need to map from a different tuple.
assert(shuffleIndex >= 0 &&
(unsigned) shuffleIndex < outerFields.size());