[llvm-commits] [vector_llvm] CVS: llvm/lib/Target/CBackend/AltiVecCTargetMachine.h AltiVecWriter.cpp AltiVecWriter.h SSECTargetMachine.h SSEWriter.cpp SSEWriter.h Writer.h

Robert Bocchino bocchino at cs.uiuc.edu
Tue Oct 18 12:37:04 PDT 2005



Changes in directory llvm/lib/Target/CBackend:

AltiVecCTargetMachine.h added (r1.1.2.1)
AltiVecWriter.cpp added (r1.1.2.1)
AltiVecWriter.h added (r1.1.2.1)
SSECTargetMachine.h added (r1.1.2.1)
SSEWriter.cpp added (r1.1.2.1)
SSEWriter.h added (r1.1.2.1)
Writer.h added (r1.1.2.1)
---
Log message:

Initial commit of Vector LLVM.


---
Diffs of the changes:  (+799 -0)

 AltiVecCTargetMachine.h |   36 ++++++
 AltiVecWriter.cpp       |  206 ++++++++++++++++++++++++++++++++++++
 AltiVecWriter.h         |   66 +++++++++++
 SSECTargetMachine.h     |   36 ++++++
 SSEWriter.cpp           |  129 +++++++++++++++++++++++
 SSEWriter.h             |   57 ++++++++++
 Writer.h                |  269 ++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 799 insertions(+)


Index: llvm/lib/Target/CBackend/AltiVecCTargetMachine.h
diff -c /dev/null llvm/lib/Target/CBackend/AltiVecCTargetMachine.h:1.1.2.1
*** /dev/null	Tue Oct 18 14:37:02 2005
--- llvm/lib/Target/CBackend/AltiVecCTargetMachine.h	Tue Oct 18 14:36:52 2005
***************
*** 0 ****
--- 1,36 ----
+ //===-- CTargetMachine.h - TargetMachine for the C backend ------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file declares the TargetMachine that is used by the AltiVec C backend.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef ALTIVECCTARGETMACHINE_H
+ #define ALTIVECCTARGETMACHINE_H
+ 
+ #include "CTargetMachine.h"
+ 
+ namespace llvm {
+ 
+ class IntrinsicLowering;
+ 
+ struct AltiVecCTargetMachine : public CTargetMachine {
+   AltiVecCTargetMachine(const Module &M, IntrinsicLowering *IL, const std::string& name) :
+     CTargetMachine(M, IL, "AltiVecCBackend") {}
+ 
+   // This is the only thing that actually does anything here.
+   bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
+ 			   CodeGenFileType FileType);
+ 
+ };
+ 
+ } // End llvm namespace
+ 
+ 
+ #endif


Index: llvm/lib/Target/CBackend/AltiVecWriter.cpp
diff -c /dev/null llvm/lib/Target/CBackend/AltiVecWriter.cpp:1.1.2.1
*** /dev/null	Tue Oct 18 14:37:03 2005
--- llvm/lib/Target/CBackend/AltiVecWriter.cpp	Tue Oct 18 14:36:52 2005
***************
*** 0 ****
--- 1,206 ----
+ //===-- Writer.cpp - Library for converting LLVM code to C ----------------===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This library converts LLVM code to C code with AltiVec extensions.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "AltiVecCTargetMachine.h"
+ #include "AltiVecWriter.h"
+ 
+ using namespace llvm;
+ 
+ namespace {
+   // Register the target.
+   RegisterTarget<AltiVecCTargetMachine> X("altivec-c", "  AltiVec C backend");
+ }
+ 
+ static void badValue(Value *V) {
+   std::cerr << "AltiVec C Backend can't handle this value!\n";
+   std::cerr << *V << "\n";
+   abort();
+ }
+ 
+ void AltiVecCWriter::printConstant(Constant *CPV) {
+   if (!isa<FixedVectorType>(CPV->getType())) {
+     CWriter::printConstant(CPV);
+     return;
+   }
+   if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
+     switch (CE->getOpcode()) {
+     case Instruction::Cast:
+       Out << "((";
+       printType(Out, CPV->getType());
+       Out << ") (";
+       printConstant(CE->getOperand(0));
+       Out << "))";
+       return;
+     default:
+       badValue(CPV);
+     }
+   }
+   // FIXME:  Add support for literal vector constants here
+   //
+   Out << "((";
+   printType(Out, CPV->getType());
+   Out << ") (";
+   for (unsigned i = 0; i < CPV->getNumOperands()-1; ++i) {
+     printConstant(CPV->getOperand(i));
+     Out << ", ";
+   }
+   printConstant(CPV->getOperand(CPV->getNumOperands()-1));
+   Out << "))";
+   return;
+ 
+ }
+ 
+ void AltiVecCWriter::visitCastInst (CastInst &I) {
+   if (!isa<FixedVectorType>(I.getType()) ||
+       isa<FixedVectorType>(I.getOperand(0)->getType()))
+     return CWriter::visitCastInst(I);
+   if (!isa<Constant>(I.getOperand(0))) {
+     std::cerr << I;
+     std::cerr << "AltiVec C Backend can handle only cast of constant to vector!\n";
+     exit(1);
+   }
+   Out << '(';
+   printType(Out, I.getType());
+   Out << ") (";
+   writeOperand(I.getOperand(0));
+   Out << ')';
+ }
+ 
+ void AltiVecCWriter::visitVImmInst (VImmInst &VL) {
+   if (!isa<Constant>(VL.getOperand(0))) {
+     std::cerr << VL;
+     std::cerr << "AltiVec C Backend can handle only vimm of constant!\n";
+     exit(1);
+   }
+   Out << '(';
+   printType(Out, VL.getType());
+   Out << ") (";
+   writeOperand(VL.getOperand(0));
+   Out << ')';
+ }
+ 
+ void AltiVecCWriter::visitBinaryOperator(Instruction &I) {
+   if (!isa<FixedVectorType>(I.getType()))
+     return CWriter::visitBinaryOperator(I);
+   switch(I.getOpcode()) {
+   case Instruction::Add:
+     // Check for mladd pattern
+     //
+     if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I.getOperand(0))) {
+       if (BO->getOpcode() == Instruction::Mul) {
+ 	Out << "vec_mladd(";
+ 	writeOperand(BO->getOperand(0));
+ 	Out << ",";
+ 	writeOperand(BO->getOperand(1));
+ 	Out << ",";
+ 	writeOperand(I.getOperand(1));
+ 	Out << ")";
+ 	break;
+       }
+     }
+     Out << "vec_add(";
+     writeOperand(I.getOperand(0));
+     Out << ",";
+     writeOperand(I.getOperand(1));
+     Out << ")";
+     break;
+   case Instruction::Mul:
+     Out << "vec_mladd(";
+     writeOperand(I.getOperand(0));
+     Out << ",";
+     writeOperand(I.getOperand(1));
+     Out << ",(vector short)(0))";
+     break;
+   case Instruction::And:
+     Out << "vec_and(";
+     writeOperand(I.getOperand(0));
+     Out << ",";
+     writeOperand(I.getOperand(1));
+     Out << ")";
+     break;
+   default:
+     std::cerr << "AltiVec C Backend can't handle this instruction:\n" << I;
+     exit(1);
+   }
+ }
+ 
+ std::ostream &AltiVecCWriter::printFixedVectorType(std::ostream &Out,
+ 						   const FixedVectorType *Ty,
+ 						   const std::string &VariableName) {
+   unsigned numElements = Ty->getNumElements();
+   switch(Ty->getElementType()->getTypeID()) {
+   case(Type::SByteTyID):
+     if (numElements != 16) {
+       std::cerr << "Vector of sbyte must have 16 elements!\n";
+       exit(1);
+     }
+     Out << "vector signed char " << VariableName;
+     break;
+   case (Type::UByteTyID):
+     if (numElements != 16) {
+       std::cerr << "Vector of ubyte must have 16 elements!\n";
+       exit(1);
+     }
+     Out << "vector unsigned char " << VariableName;
+     break;
+   case(Type::ShortTyID):
+     if (numElements != 8) {
+       std::cerr << "Vector of short must have 8 elements!\n";
+       exit(1);
+     }
+     Out << "vector signed short " << VariableName;
+     break;
+   case(Type::UShortTyID):
+     if (numElements != 8) {
+       std::cerr << "Vector of ushort must have 8 elements!\n";
+       exit(1);
+     }
+     Out << "vector unsigned short " << VariableName;
+     break;
+   case(Type::BoolTyID):
+     switch(numElements) {
+     case 8:
+       Out << "vector bool short ";
+       break;
+     default:
+       std::cerr << "AltiVec C Backend cannot handle boolean vector with "
+ 		<< numElements << " elements!\n";
+       break;
+     }
+     Out << VariableName;
+     break;
+   default:
+     std::cerr << "AltiVec C Backend cannot handle " << Ty->getDescription() << "!\n";
+     exit(1);
+     break;
+   }
+   return Out;
+ }
+ 
+ 
+ //===----------------------------------------------------------------------===//
+ //                       External Interface declaration
+ //===----------------------------------------------------------------------===//
+ 
+ bool AltiVecCTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &o,
+ 						CodeGenFileType FileType) {
+   if (FileType != TargetMachine::AssemblyFile) return true;
+   // Add lowervectors pass here to lower variable-length vectors, which we can't handle
+   PM.add(createLowerGCPass());
+   PM.add(createLowerAllocationsPass(true));
+   PM.add(createLowerInvokePass());
+   PM.add(new CBackendNameAllUsedStructs());
+   PM.add(new AltiVecCWriter(o, getIntrinsicLowering()));
+   return false;
+ }
+ 


Index: llvm/lib/Target/CBackend/AltiVecWriter.h
diff -c /dev/null llvm/lib/Target/CBackend/AltiVecWriter.h:1.1.2.1
*** /dev/null	Tue Oct 18 14:37:03 2005
--- llvm/lib/Target/CBackend/AltiVecWriter.h	Tue Oct 18 14:36:52 2005
***************
*** 0 ****
--- 1,66 ----
+ //===---------------- Writer.h - C backend interface ------------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file exposes the interface that is common to all C backends.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef ALTIVECCWRITER_H
+ #define ALTIVECCWRITER_H
+ 
+ #include "Writer.h"
+ 
+ using namespace llvm;
+ 
+ namespace llvm {
+   /// AltiVecCWriter - This class is the main chunk of code that
+   /// converts an LLVM module to an AltiVec/C translation unit.
+   class AltiVecCWriter : public CWriter {
+     void printConstant(Constant *CPV);
+     void visitCastInst(CastInst &I);
+     void visitVImmInst(VImmInst &I);
+     void visitBinaryOperator(Instruction &I);
+ 
+   public:
+     AltiVecCWriter(std::ostream &o, IntrinsicLowering &il) : 
+       CWriter(o,il) {}
+ 
+     void writeValueName(Value *V) {
+       std::string name = Mang->getValueName(V);
+       if (name.substr(0,8) == "altivec_") {
+ 	unsigned pos = name.find("_", 8);
+ 	if (pos == std::string::npos) {
+ 	  std::cerr << "Bad syntax for AltiVec intrinsic " << name << "\n";
+ 	  exit(1);
+ 	}
+ 	// C name is vec_xxx
+ 	Out << name.substr(4, pos-4);
+       } else {
+ 	CWriter::writeValueName(V);
+       }
+     }
+ 
+     bool printDeclarationFor(Function *F) {
+       if (F->getName().substr(0, 7) == "altivec")
+ 	return false;
+       return CWriter::printDeclarationFor(F);
+     }
+     virtual const char *getPassName() const { return "AltiVec C backend"; }
+ 
+     std::ostream &printFixedVectorType(std::ostream &Out,
+ 				       const FixedVectorType *Ty,
+ 				       const std::string &VariableName = "");
+ 
+   };
+ }
+ 
+ 
+ 
+ #endif
+ 


Index: llvm/lib/Target/CBackend/SSECTargetMachine.h
diff -c /dev/null llvm/lib/Target/CBackend/SSECTargetMachine.h:1.1.2.1
*** /dev/null	Tue Oct 18 14:37:03 2005
--- llvm/lib/Target/CBackend/SSECTargetMachine.h	Tue Oct 18 14:36:52 2005
***************
*** 0 ****
--- 1,36 ----
+ //===-- CTargetMachine.h - TargetMachine for the C backend ------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file declares the TargetMachine that is used by the SSE C backend.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef SSECTARGETMACHINE_H
+ #define SSECTARGETMACHINE_H
+ 
+ #include "CTargetMachine.h"
+ 
+ namespace llvm {
+ 
+ class IntrinsicLowering;
+ 
+ struct SSECTargetMachine : public CTargetMachine {
+   SSECTargetMachine(const Module &M, IntrinsicLowering *IL, const std::string& name) :
+     CTargetMachine(M, IL, "SSECBackend") {}
+ 
+   // This is the only thing that actually does anything here.
+   bool addPassesToEmitFile(PassManager &PM, std::ostream &Out,
+ 			   CodeGenFileType FileType);
+ 
+ };
+ 
+ } // End llvm namespace
+ 
+ 
+ #endif


Index: llvm/lib/Target/CBackend/SSEWriter.cpp
diff -c /dev/null llvm/lib/Target/CBackend/SSEWriter.cpp:1.1.2.1
*** /dev/null	Tue Oct 18 14:37:03 2005
--- llvm/lib/Target/CBackend/SSEWriter.cpp	Tue Oct 18 14:36:52 2005
***************
*** 0 ****
--- 1,129 ----
+ //===-- Writer.cpp - Library for converting LLVM code to C ----------------===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This library converts LLVM code to C code with SSE extensions.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "SSECTargetMachine.h"
+ #include "SSEWriter.h"
+ 
+ using namespace llvm;
+ 
+ namespace {
+   // Register the target.
+   RegisterTarget<SSECTargetMachine> X("sse-c", "  SSE C backend");
+ }
+ 
+ static void badValue(Value *V) {
+   std::cerr << "SSE C Backend can't handle this value!\n";
+   std::cerr << *V << "\n";
+   abort();
+ }
+ 
+ void SSECWriter::printConstant(Constant *CPV) {
+   if (!isa<FixedVectorType>(CPV->getType())) {
+     CWriter::printConstant(CPV);
+     return;
+   }
+   if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
+     switch (CE->getOpcode()) {
+     case Instruction::Cast:
+       Out << "((";
+       printType(Out, CPV->getType());
+       Out << ") (";
+       printConstant(CE->getOperand(0));
+       Out << "))";
+       return;
+     default:
+       badValue(CPV);
+     }
+   }
+   // FIXME:  Add support for literal vector constants here
+   //
+   Out << "((";
+   printType(Out, CPV->getType());
+   Out << ") (";
+   for (unsigned i = 0; i < CPV->getNumOperands()-1; ++i) {
+     printConstant(CPV->getOperand(i));
+     Out << ", ";
+   }
+   printConstant(CPV->getOperand(CPV->getNumOperands()-1));
+   Out << "))";
+   return;
+ 
+ }
+ 
+ void SSECWriter::visitCastInst (CastInst &I) {
+   if (!isa<FixedVectorType>(I.getType()) ||
+       isa<FixedVectorType>(I.getOperand(0)->getType()))
+     return CWriter::visitCastInst(I);
+   std::cerr << I;
+   std::cerr << "SSE C Backend cannot handle this cast!\n";
+ }
+ 
+ void SSECWriter::visitBinaryOperator(Instruction &I) {
+   if (!isa<FixedVectorType>(I.getType()))
+     return CWriter::visitBinaryOperator(I);
+   switch(I.getOpcode()) {
+   case Instruction::Add:
+     Out << "_mm_add_epi16(";
+     writeOperand(I.getOperand(0));
+     Out << ",";
+     writeOperand(I.getOperand(1));
+     Out << ")";
+     break;
+   case Instruction::Mul:
+     Out << "_mm_mullo_epi16(";
+     writeOperand(I.getOperand(0));
+     Out << ",";
+     writeOperand(I.getOperand(1));
+     Out << ")";
+     break;
+   case Instruction::And:
+     Out << "_mm_and_si128(";
+     writeOperand(I.getOperand(0));
+     Out << ",";
+     writeOperand(I.getOperand(1));
+     Out << ")";
+     break;
+   default:
+     std::cerr << "SSE C Backend can't handle this instruction:\n" << I;
+     exit(1);
+   }
+ }
+ 
+ std::ostream &SSECWriter::printFixedVectorType(std::ostream &Out,
+ 					       const FixedVectorType *Ty,
+ 					       const std::string &VariableName) {
+   if (Ty->isIntegralVector()) {
+     Out << "__m128i " << VariableName;
+   } else {
+     std::cerr << "SSE C Backend cannot handle type!\n" << Ty->getDescription() << "\n";
+     exit(1);
+   }
+   return Out;
+ }
+ 
+ 
+ //===----------------------------------------------------------------------===//
+ //                       External Interface declaration
+ //===----------------------------------------------------------------------===//
+ 
+ bool SSECTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &o,
+ 					    CodeGenFileType FileType) {
+   if (FileType != TargetMachine::AssemblyFile) return true;
+   // Add lowervectors pass here to lower variable-length vectors, which we can't handle
+   PM.add(createLowerGCPass());
+   PM.add(createLowerAllocationsPass(true));
+   PM.add(createLowerInvokePass());
+   PM.add(new CBackendNameAllUsedStructs());
+   PM.add(new SSECWriter(o, getIntrinsicLowering()));
+   return false;
+ }


Index: llvm/lib/Target/CBackend/SSEWriter.h
diff -c /dev/null llvm/lib/Target/CBackend/SSEWriter.h:1.1.2.1
*** /dev/null	Tue Oct 18 14:37:03 2005
--- llvm/lib/Target/CBackend/SSEWriter.h	Tue Oct 18 14:36:52 2005
***************
*** 0 ****
--- 1,57 ----
+ //===---------------- Writer.h - C backend interface ------------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file exposes the interface that is common to all C backends.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef SSECWRITER_H
+ #define SSECWRITER_H
+ 
+ #include "Writer.h"
+ 
+ using namespace llvm;
+ 
+ namespace llvm {
+   /// SSECWriter - This class is the main chunk of code that
+   /// converts an LLVM module to an SSE/C translation unit.
+   class SSECWriter : public CWriter {
+     void printConstant(Constant *CPV);
+     void visitCastInst (CastInst &I);
+     void visitBinaryOperator(Instruction &I);
+ 
+   public:
+     SSECWriter(std::ostream &o, IntrinsicLowering &il) : 
+       CWriter(o,il) {}
+ 
+     // Provide declaration for SSE intrinsics
+     //
+     bool doInitialization(Module &M) {
+       Out << "#include \"SSE.h\"\n";
+       return CWriter::doInitialization(M);
+     }
+ 
+     bool printDeclarationFor(Function *F) {
+       if (F->getName().substr(0, 4) == "_mm_")
+ 	return false;
+       return CWriter::printDeclarationFor(F);
+     }
+     virtual const char *getPassName() const { return "SSE C backend"; }
+ 
+     std::ostream &printFixedVectorType(std::ostream &Out,
+ 				       const FixedVectorType *Ty,
+ 				       const std::string &VariableName = "");
+ 
+   };
+ }
+ 
+ 
+ 
+ #endif
+ 


Index: llvm/lib/Target/CBackend/Writer.h
diff -c /dev/null llvm/lib/Target/CBackend/Writer.h:1.1.2.1
*** /dev/null	Tue Oct 18 14:37:03 2005
--- llvm/lib/Target/CBackend/Writer.h	Tue Oct 18 14:36:52 2005
***************
*** 0 ****
--- 1,269 ----
+ //===---------------- Writer.h - C backend interface ------------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file exposes the interface that is common to all C backends.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef CWRITER_H
+ #define CWRITER_H
+ 
+ #include "llvm/Constants.h"
+ #include "llvm/DerivedTypes.h"
+ #include "llvm/Module.h"
+ #include "llvm/Instructions.h"
+ #include "llvm/Pass.h"
+ #include "llvm/PassManager.h"
+ #include "llvm/SymbolTable.h"
+ #include "llvm/Intrinsics.h"
+ #include "llvm/Analysis/ConstantsScanner.h"
+ #include "llvm/Analysis/FindUsedTypes.h"
+ #include "llvm/Analysis/LoopInfo.h"
+ #include "llvm/CodeGen/IntrinsicLowering.h"
+ #include "llvm/Transforms/Scalar.h"
+ #include "llvm/Target/TargetMachineRegistry.h"
+ #include "llvm/Support/CallSite.h"
+ #include "llvm/Support/CFG.h"
+ #include "llvm/Support/GetElementPtrTypeIterator.h"
+ #include "llvm/Support/InstVisitor.h"
+ #include "llvm/Support/Mangler.h"
+ #include "llvm/ADT/StringExtras.h"
+ #include "llvm/ADT/STLExtras.h"
+ #include "llvm/Support/MathExtras.h"
+ #include "llvm/Config/config.h"
+ #include <algorithm>
+ #include <iostream>
+ #include <sstream>
+ 
+ using namespace llvm;
+ 
+ namespace llvm {
+   /// NameAllUsedStructs - This pass inserts names for any unnamed structure
+   /// types that are used by the program.
+   ///
+   class CBackendNameAllUsedStructs : public ModulePass {
+     void getAnalysisUsage(AnalysisUsage &AU) const {
+       AU.addRequired<FindUsedTypes>();
+     }
+ 
+     virtual const char *getPassName() const {
+       return "C backend type canonicalizer";
+     }
+ 
+     virtual bool runOnModule(Module &M);
+   };
+ 
+   /// CWriter - This class is the main chunk of code that converts an LLVM
+   /// module to a C translation unit.
+   class CWriter : public FunctionPass, public InstVisitor<CWriter> {
+   protected:
+     std::ostream &Out;
+     IntrinsicLowering &IL;
+     Mangler *Mang;
+     LoopInfo *LI;
+     const Module *TheModule;
+     std::map<const Type *, std::string> TypeNames;
+ 
+     std::map<const ConstantFP *, unsigned> FPConstantMap;
+   public:
+     CWriter(std::ostream &o, IntrinsicLowering &il) : Out(o), IL(il) {}
+ 
+     virtual const char *getPassName() const { return "C backend"; }
+ 
+     void getAnalysisUsage(AnalysisUsage &AU) const {
+       AU.addRequired<LoopInfo>();
+       AU.setPreservesAll();
+     }
+ 
+     virtual bool printDeclarationFor(Function *F);
+     virtual bool doInitialization(Module &M);
+ 
+     bool runOnFunction(Function &F) {
+       LI = &getAnalysis<LoopInfo>();
+ 
+       // Get rid of intrinsics we can't handle.
+       lowerIntrinsics(F);
+ 
+       // Output all floating point constants that cannot be printed accurately.
+       printFloatingPointConstants(F);
+ 
+       // Ensure that no local symbols conflict with global symbols.
+       F.renameLocalSymbols();
+ 
+       printFunction(F);
+       FPConstantMap.clear();
+       return false;
+     }
+ 
+     virtual bool doFinalization(Module &M) {
+       // Free memory...
+       delete Mang;
+       TypeNames.clear();
+       return false;
+     }
+ 
+     std::ostream &printType(std::ostream &Out, const Type *Ty,
+                             const std::string &VariableName = "",
+                             bool IgnoreName = false);
+ 
+     // Methods for printing vector types; these can be overridden by
+     // target-specific subclasses (AltiVec, SSE, etc.)
+     //
+     virtual std::ostream &printFixedVectorType(std::ostream &Out,
+ 					       const FixedVectorType *Ty,
+ 					       const std::string &VariableName = "") {
+       // FIXME:  Insert lowering so this never happens
+       //
+       std::cerr << "Backend cannot handle vector types!\n";
+       exit(1);
+     }
+ 
+     virtual std::ostream &printVectorType(std::ostream &Out,
+ 					  const VectorType *Ty,
+ 					  const std::string &VariableName = "") {
+       // FIXME:  Insert lowering so this never happens
+       // 
+       std::cerr << "Backend cannot handle vector types!\n";
+       exit(1);
+     }
+ 
+     virtual void writeValueName(Value *V);
+     void writeOperand(Value *Operand);
+     void writeOperandInternal(Value *Operand);
+ 
+   protected:
+     void lowerIntrinsics(Function &F);
+ 
+     bool nameAllUsedStructureTypes(Module &M);
+     void printModule(Module *M);
+     void printModuleTypes(const SymbolTable &ST);
+     void printContainedStructs(const Type *Ty, std::set<const StructType *> &);
+     void printFloatingPointConstants(Function &F);
+     void printFunctionSignature(const Function *F, bool Prototype);
+ 
+     void printFunction(Function &);
+     void printBasicBlock(BasicBlock *BB);
+     void printLoop(Loop *L);
+ 
+     virtual void printConstant(Constant *CPV);
+     void printConstantArray(ConstantArray *CPA);
+ 
+     // isInlinableInst - Attempt to inline instructions into their uses to build
+     // trees as much as possible.  To do this, we have to consistently decide
+     // what is acceptable to inline, so that variable declarations don't get
+     // printed and an extra copy of the expr is not emitted.
+     //
+     static bool isInlinableInst(const Instruction &I) {
+       // Always inline setcc instructions, even if they are shared by multiple
+       // expressions.  GCC generates horrible code if we don't.
+       if (isa<SetCondInst>(I)) return true;
+ 
+       // Must be an expression, must be used exactly once.  If it is dead, we
+       // 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))
+         // Don't inline a load across a store or other bad things!
+         return false;
+ 
+       // Only inline instruction if its use is in the same BB as the inst.
+       return I.getParent() == cast<Instruction>(I.use_back())->getParent();
+    }
+ 
+     static const bool isSafeUse(const Value *user, const Value *use) {
+       if (isa<LoadInst>(user))
+ 	return true;
+       if (const StoreInst *SI = dyn_cast<StoreInst>(user))
+ 	return (use == SI->getOperand(1));
+       if (isa<CastInst>(user)) {
+ 	return isSafeUser(user);
+       }
+       return false;
+     }
+ 
+     static const bool isSafeUser(const Value *user) {
+       for (User::use_const_iterator I = user->use_begin(),
+ 	     E = user->use_end(); I != E; ++I)
+ 	if (!isSafeUse(*I, user))
+ 	  return false;
+       return true;
+     }
+ 
+     // isDirectAlloca - Define fixed sized allocas in the entry block
+     // as direct variables which are accessed with the & operator.
+     // This causes GCC to generate significantly better code than to
+     // emit alloca calls directly.
+     //
+     static const AllocaInst *isDirectAlloca(const Value *V) {
+       const AllocaInst *AI = dyn_cast<AllocaInst>(V);
+       if (!AI) return false;
+       if (AI->isArrayAllocation())
+         return 0;   // FIXME: we can also inline fixed size array allocas!
+       if (AI->getParent() != &AI->getParent()->getParent()->getEntryBlock())
+ 	if (!isSafeUser(AI))
+ 	  return 0;
+       return AI;
+     }
+ 
+     // Instruction visitation functions
+     friend class InstVisitor<CWriter>;
+ 
+     void visitReturnInst(ReturnInst &I);
+     void visitBranchInst(BranchInst &I);
+     void visitSwitchInst(SwitchInst &I);
+     void visitInvokeInst(InvokeInst &I) {
+       assert(0 && "Lowerinvoke pass didn't work!");
+     }
+ 
+     void visitUnwindInst(UnwindInst &I) {
+       assert(0 && "Lowerinvoke pass didn't work!");
+     }
+     void visitUnreachableInst(UnreachableInst &I);
+ 
+     void visitPHINode(PHINode &I);
+     virtual void visitBinaryOperator(Instruction &I);
+ 
+     virtual void visitCastInst (CastInst &I);
+     virtual void visitVImmInst(VImmInst &VL) { visitInstruction(VL); }
+     void visitSelectInst(SelectInst &I);
+     void visitCallInst (CallInst &I);
+     void visitShiftInst(ShiftInst &I) { visitBinaryOperator(I); }
+ 
+     void visitMallocInst(MallocInst &I);
+     void visitAllocaInst(AllocaInst &I);
+     void visitFreeInst  (FreeInst   &I);
+     void visitLoadInst  (LoadInst   &I);
+     void visitStoreInst (StoreInst  &I);
+     void visitGetElementPtrInst(GetElementPtrInst &I);
+     //void visitVANextInst(VANextInst &I);
+     void visitVAArgInst (VAArgInst &I);
+ 
+     void visitInstruction(Instruction &I) {
+       std::cerr << "C Writer does not know about " << I;
+       abort();
+     }
+ 
+     void outputLValue(Instruction *I) {
+       Out << "  " << Mang->getValueName(I) << " = ";
+     }
+ 
+     bool isGotoCodeNecessary(BasicBlock *From, BasicBlock *To);
+     void printPHICopiesForSuccessor(BasicBlock *CurBlock,
+                                     BasicBlock *Successor, unsigned Indent);
+     void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock,
+                             unsigned Indent);
+     void printIndexingExpression(Value *Ptr, gep_type_iterator I,
+                                  gep_type_iterator E);
+   };
+ }
+ 
+ 
+ 
+ #endif
+ 






More information about the llvm-commits mailing list