00001 //===-- codegen/CodeGenTypes.cpp ------------------------------ -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2009, Stephen Wilson 00006 // 00007 //===----------------------------------------------------------------------===// 00008 00009 #include "comma/ast/Decl.h" 00010 #include "comma/codegen/CodeGen.h" 00011 #include "comma/codegen/CodeGenTypes.h" 00012 #include "comma/codegen/CommaRT.h" 00013 00014 #include "llvm/DerivedTypes.h" 00015 #include "llvm/Support/MathExtras.h" 00016 00017 using namespace comma; 00018 00019 using llvm::dyn_cast; 00020 using llvm::cast; 00021 using llvm::isa; 00022 00023 const llvm::Type *CodeGenTypes::lowerType(Type *type) 00024 { 00025 switch (type->getKind()) { 00026 00027 default: 00028 assert(false && "Cannot lower the given Type!"); 00029 return 0; 00030 00031 case Ast::AST_DomainType: 00032 return lowerType(cast<DomainType>(type)); 00033 00034 case Ast::AST_CarrierType: 00035 return lowerType(cast<CarrierType>(type)); 00036 00037 case Ast::AST_EnumerationType: 00038 return lowerType(cast<EnumerationType>(type)); 00039 00040 case Ast::AST_TypedefType: 00041 return lowerType(cast<TypedefType>(type)); 00042 00043 case Ast::AST_FunctionType: 00044 case Ast::AST_ProcedureType: 00045 return lowerType(cast<SubroutineType>(type)); 00046 } 00047 } 00048 00049 const llvm::Type *CodeGenTypes::lowerType(DomainType *type) 00050 { 00051 // If the given domain type denotes `%', lower it to a generic i8*. 00052 if (type->denotesPercent()) 00053 return CG.getPointerType(llvm::Type::Int8Ty); 00054 00055 assert(false && "Cannot lower this domain type yet!"); 00056 } 00057 00058 const llvm::Type *CodeGenTypes::lowerType(CarrierType *type) 00059 { 00060 return lowerType(type->getRepresentationType()); 00061 } 00062 00063 const llvm::IntegerType *CodeGenTypes::lowerType(EnumerationType *type) 00064 { 00065 // Enumeration types are lowered to an integer type with sufficient capacity 00066 // to hold each element of the enumeration. 00067 EnumerationDecl *decl = type->getEnumerationDecl(); 00068 unsigned numBits = llvm::Log2_32_Ceil(decl->getNumLiterals()); 00069 00070 return getTypeForWidth(numBits); 00071 } 00072 00073 const llvm::FunctionType *CodeGenTypes::lowerType(const SubroutineType *type) 00074 { 00075 std::vector<const llvm::Type*> args; 00076 const llvm::FunctionType *result; 00077 00078 // Emit the implicit first "%" argument. 00079 args.push_back(CG.getRuntime().getType<CommaRT::CRT_DomainInstance>()); 00080 00081 for (unsigned i = 0; i < type->getArity(); ++i) { 00082 const llvm::Type *argTy = lowerType(type->getArgType(i)); 00083 00084 // If the argument mode is "out" or "in out", make the argument a 00085 // pointer-to type. 00086 PM::ParameterMode mode = type->getParameterMode(i); 00087 if (mode == PM::MODE_OUT or mode == PM::MODE_IN_OUT) 00088 argTy = CG.getPointerType(argTy); 00089 00090 args.push_back(argTy); 00091 } 00092 00093 if (const FunctionType *ftype = dyn_cast<FunctionType>(type)) 00094 result = llvm::FunctionType::get(lowerType(ftype->getReturnType()), args, false); 00095 else 00096 result = llvm::FunctionType::get(llvm::Type::VoidTy, args, false); 00097 00098 return result; 00099 } 00100 00101 const llvm::IntegerType *CodeGenTypes::lowerType(const TypedefType *type) 00102 { 00103 // Currently, all TypedefType's are Integer types. 00104 const IntegerType *baseType = cast<IntegerType>(type->getBaseType()); 00105 return lowerType(baseType); 00106 } 00107 00108 const llvm::IntegerType *CodeGenTypes::lowerType(const IntegerType *type) 00109 { 00110 return getTypeForWidth(type->getBitWidth()); 00111 } 00112 00113 const llvm::IntegerType *CodeGenTypes::getTypeForWidth(unsigned numBits) 00114 { 00115 // Promote the bit width to a power of two. 00116 if (numBits <= 1) 00117 return llvm::Type::Int1Ty; 00118 if (numBits <= 8) 00119 return llvm::Type::Int8Ty; 00120 else if (numBits <= 16) 00121 return llvm::Type::Int16Ty; 00122 else if (numBits <= 32) 00123 return llvm::Type::Int32Ty; 00124 else if (numBits <= 64) 00125 return llvm::Type::Int64Ty; 00126 else { 00127 // FIXME: This should be a fatal error, not an assert. 00128 assert(false && "Enumeration type too large to codegen!"); 00129 return 0; 00130 } 00131 }