[llvm-commits] [llvm] r51881 - in /llvm/trunk: lib/Target/CBackend/CBackend.cpp test/CodeGen/CBackend/2007-01-15-NamedArrayType.ll
Dan Gohman
gohman at apple.com
Mon Jun 2 14:30:50 PDT 2008
Author: djg
Date: Mon Jun 2 16:30:49 2008
New Revision: 51881
URL: http://llvm.org/viewvc/llvm-project?rev=51881&view=rev
Log:
Implement CBE support for first-class structs and array values,
and insertvalue and extractvalue instructions.
First-class array values are not trivial because C doesn't
support them. The approach I took here is to wrap all arrays
in structs. Feedback is welcome.
The 2007-01-15-NamedArrayType.ll test needed to be modified
because it has a "not grep" for a string that now exists,
because array types now have associated struct types, and
those struct types have names.
Modified:
llvm/trunk/lib/Target/CBackend/CBackend.cpp
llvm/trunk/test/CodeGen/CBackend/2007-01-15-NamedArrayType.ll
Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=51881&r1=51880&r2=51881&view=diff
==============================================================================
--- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original)
+++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Mon Jun 2 16:30:49 2008
@@ -171,7 +171,7 @@
void printModule(Module *M);
void printModuleTypes(const TypeSymbolTable &ST);
- void printContainedStructs(const Type *Ty, std::set<const StructType *> &);
+ void printContainedStructs(const Type *Ty, std::set<const Type *> &);
void printFloatingPointConstants(Function &F);
void printFunctionSignature(const Function *F, bool Prototype);
@@ -210,7 +210,8 @@
// emit it inline where it would go.
if (I.getType() == Type::VoidTy || !I.hasOneUse() ||
isa<TerminatorInst>(I) || isa<CallInst>(I) || isa<PHINode>(I) ||
- isa<LoadInst>(I) || isa<VAArgInst>(I) || isa<InsertElementInst>(I))
+ isa<LoadInst>(I) || isa<VAArgInst>(I) || isa<InsertElementInst>(I) ||
+ isa<InsertValueInst>(I))
// Don't inline a load across a store or other bad things!
return false;
@@ -286,6 +287,9 @@
void visitShuffleVectorInst(ShuffleVectorInst &SVI);
void visitGetResultInst(GetResultInst &GRI);
+ void visitInsertValueInst(InsertValueInst &I);
+ void visitExtractValueInst(ExtractValueInst &I);
+
void visitInstruction(Instruction &I) {
cerr << "C Writer does not know about " << I;
abort();
@@ -325,9 +329,10 @@
TI != TE; ) {
TypeSymbolTable::iterator I = TI++;
- // If this isn't a struct type, remove it from our set of types to name.
- // This simplifies emission later.
- if (!isa<StructType>(I->second) && !isa<OpaqueType>(I->second)) {
+ // If this isn't a struct or array type, remove it from our set of types
+ // to name. This simplifies emission later.
+ if (!isa<StructType>(I->second) && !isa<OpaqueType>(I->second) &&
+ !isa<ArrayType>(I->second)) {
TST.remove(I);
} else {
// If this is not used, remove it from the symbol table.
@@ -346,8 +351,8 @@
unsigned RenameCounter = 0;
for (std::set<const Type *>::const_iterator I = UT.begin(), E = UT.end();
I != E; ++I)
- if (const StructType *ST = dyn_cast<StructType>(*I)) {
- while (M.addTypeName("unnamed"+utostr(RenameCounter), ST))
+ if (isa<StructType>(*I) || isa<ArrayType>(*I)) {
+ while (M.addTypeName("unnamed"+utostr(RenameCounter), *I))
++RenameCounter;
Changed = true;
}
@@ -557,8 +562,12 @@
const ArrayType *ATy = cast<ArrayType>(Ty);
unsigned NumElements = ATy->getNumElements();
if (NumElements == 0) NumElements = 1;
- return printType(Out, ATy->getElementType(), false,
- NameSoFar + "[" + utostr(NumElements) + "]");
+ // Arrays are wrapped in structs to allow them to have normal
+ // value semantics (avoiding the array "decay").
+ Out << NameSoFar << " { ";
+ printType(Out, ATy->getElementType(), false,
+ "array[" + utostr(NumElements) + "]");
+ return Out << "; }";
}
case Type::OpaqueTyID: {
@@ -1013,6 +1022,7 @@
}
case Type::ArrayTyID:
+ Out << "{ "; // Arrays are wrapped in struct types.
if (ConstantArray *CA = dyn_cast<ConstantArray>(CPV)) {
printConstantArray(CA);
} else {
@@ -1030,6 +1040,7 @@
}
Out << " }";
}
+ Out << " }"; // Arrays are wrapped in struct types.
break;
case Type::VectorTyID:
@@ -1760,9 +1771,12 @@
// the compiler figure out the rest of the zeros.
Out << " = " ;
if (isa<StructType>(I->getInitializer()->getType()) ||
- isa<ArrayType>(I->getInitializer()->getType()) ||
isa<VectorType>(I->getInitializer()->getType())) {
Out << "{ 0 }";
+ } else if (isa<ArrayType>(I->getInitializer()->getType())) {
+ // As with structs and vectors, but with an extra set of braces
+ // because arrays are wrapped in structs.
+ Out << "{ { 0 } }";
} else {
// Just print it out normally.
writeOperand(I->getInitializer());
@@ -1904,16 +1918,16 @@
Out << '\n';
// Keep track of which structures have been printed so far...
- std::set<const StructType *> StructPrinted;
+ std::set<const Type *> StructPrinted;
// Loop over all structures then push them into the stack so they are
// printed in the correct order.
//
Out << "/* Structure contents */\n";
for (I = TST.begin(); I != End; ++I)
- if (const StructType *STy = dyn_cast<StructType>(I->second))
+ if (isa<StructType>(I->second) || isa<ArrayType>(I->second))
// Only print out used types!
- printContainedStructs(STy, StructPrinted);
+ printContainedStructs(I->second, StructPrinted);
}
// Push the struct onto the stack and recursively push all structs
@@ -1922,7 +1936,7 @@
// TODO: Make this work properly with vector types
//
void CWriter::printContainedStructs(const Type *Ty,
- std::set<const StructType*> &StructPrinted){
+ std::set<const Type*> &StructPrinted) {
// Don't walk through pointers.
if (isa<PointerType>(Ty) || Ty->isPrimitiveType() || Ty->isInteger()) return;
@@ -1931,12 +1945,12 @@
E = Ty->subtype_end(); I != E; ++I)
printContainedStructs(*I, StructPrinted);
- if (const StructType *STy = dyn_cast<StructType>(Ty)) {
+ if (isa<StructType>(Ty) || isa<ArrayType>(Ty)) {
// Check to see if we have already printed this struct.
- if (StructPrinted.insert(STy).second) {
+ if (StructPrinted.insert(Ty).second) {
// Print structure type out.
- std::string Name = TypeNames[STy];
- printType(Out, STy, false, Name, true);
+ std::string Name = TypeNames[Ty];
+ printType(Out, Ty, false, Name, true);
Out << ";\n\n";
}
}
@@ -3097,6 +3111,10 @@
for (; I != E; ++I) {
if (isa<StructType>(*I)) {
Out << ".field" << cast<ConstantInt>(I.getOperand())->getZExtValue();
+ } else if (isa<ArrayType>(*I)) {
+ Out << ".array[";
+ writeOperandWithCast(I.getOperand(), Instruction::GetElementPtr);
+ Out << ']';
} else if (!isa<VectorType>(*I)) {
Out << '[';
writeOperandWithCast(I.getOperand(), Instruction::GetElementPtr);
@@ -3255,6 +3273,47 @@
Out << ")";
}
+void CWriter::visitInsertValueInst(InsertValueInst &IVI) {
+ // Start by copying the entire aggregate value into the result variable.
+ writeOperand(IVI.getOperand(0));
+ Out << ";\n ";
+
+ // Then do the insert to update the field.
+ Out << GetValueName(&IVI);
+ for (const unsigned *b = IVI.idx_begin(), *i = b, *e = IVI.idx_end();
+ i != e; ++i) {
+ const Type *IndexedTy =
+ ExtractValueInst::getIndexedType(IVI.getOperand(0)->getType(), b, i+1);
+ if (isa<ArrayType>(IndexedTy))
+ Out << ".array[" << *i << "]";
+ else
+ Out << ".field" << *i;
+ }
+ Out << " = ";
+ writeOperand(IVI.getOperand(1));
+}
+
+void CWriter::visitExtractValueInst(ExtractValueInst &EVI) {
+ Out << "(";
+ if (isa<UndefValue>(EVI.getOperand(0))) {
+ Out << "(";
+ printType(Out, EVI.getType());
+ Out << ") 0/*UNDEF*/";
+ } else {
+ Out << GetValueName(EVI.getOperand(0));
+ for (const unsigned *b = EVI.idx_begin(), *i = b, *e = EVI.idx_end();
+ i != e; ++i) {
+ const Type *IndexedTy =
+ ExtractValueInst::getIndexedType(EVI.getOperand(0)->getType(), b, i+1);
+ if (isa<ArrayType>(IndexedTy))
+ Out << ".array[" << *i << "]";
+ else
+ Out << ".field" << *i;
+ }
+ }
+ Out << ")";
+}
+
//===----------------------------------------------------------------------===//
// External Interface declaration
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/test/CodeGen/CBackend/2007-01-15-NamedArrayType.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CBackend/2007-01-15-NamedArrayType.ll?rev=51881&r1=51880&r2=51881&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/CBackend/2007-01-15-NamedArrayType.ll (original)
+++ llvm/trunk/test/CodeGen/CBackend/2007-01-15-NamedArrayType.ll Mon Jun 2 16:30:49 2008
@@ -1,5 +1,5 @@
; PR918
-; RUN: llvm-as < %s | llc -march=c | not grep fixarray_array3
+; RUN: llvm-as < %s | llc -march=c | not grep {l_structtype_s l_fixarray_array3}
%structtype_s = type { i32 }
%fixarray_array3 = type [3 x %structtype_s]
More information about the llvm-commits
mailing list