This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- codegen/CodeGenRoutine.cpp ---------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2009-2010, Stephen Wilson 00006 // 00007 //===----------------------------------------------------------------------===// 00008 00009 #include "BoundsEmitter.h" 00010 #include "CGContext.h" 00011 #include "CodeGenRoutine.h" 00012 #include "CodeGenTypes.h" 00013 #include "CommaRT.h" 00014 #include "SRInfo.h" 00015 #include "comma/ast/AttribExpr.h" 00016 #include "comma/ast/Decl.h" 00017 #include "comma/ast/Expr.h" 00018 #include "comma/ast/Pragma.h" 00019 #include "comma/ast/RangeAttrib.h" 00020 #include "comma/ast/Stmt.h" 00021 #include "comma/codegen/Mangle.h" 00022 00023 #include "llvm/Analysis/Verifier.h" 00024 00025 using namespace comma; 00026 00027 using llvm::dyn_cast; 00028 using llvm::dyn_cast_or_null; 00029 using llvm::cast; 00030 using llvm::isa; 00031 00032 CodeGenRoutine::CodeGenRoutine(CGContext &CGC, SRInfo *info) 00033 : CG(CGC.getCG()), 00034 CGC(CGC), 00035 CGT(CGC.getCGT()), 00036 CRT(CG.getRuntime()), 00037 SRI(info), 00038 Builder(CG.getLLVMContext()), 00039 SRF(0) { } 00040 00041 void CodeGenRoutine::emit() 00042 { 00043 // If this declaration is imported (pragma import as completion), we are 00044 // done. 00045 if (SRI->isImported()) 00046 return; 00047 00048 // We need to codegen this subroutine. Obtain a frame. 00049 std::auto_ptr<SRFrame> SRFHandle(new SRFrame(SRI, *this, Builder)); 00050 SRF = SRFHandle.get(); 00051 emitSubroutineBody(); 00052 llvm::verifyFunction(*SRI->getLLVMFunction()); 00053 } 00054 00055 void CodeGenRoutine::emitSubroutineBody() 00056 { 00057 // Resolve the completion for this subroutine, if needed. 00058 SubroutineDecl *SRDecl = SRI->getDeclaration(); 00059 if (SRDecl->getDefiningDeclaration()) 00060 SRDecl = SRDecl->getDefiningDeclaration(); 00061 00062 // Codegen the function body. If the resulting insertion context is not 00063 // properly terminated, create a branch to the return BB. 00064 BlockStmt *body = SRDecl->getBody(); 00065 llvm::BasicBlock *bodyBB = emitBlockStmt(body, 0); 00066 if (!Builder.GetInsertBlock()->getTerminator()) 00067 SRF->emitReturn(); 00068 00069 SRF->emitPrologue(bodyBB); 00070 SRF->emitEpilogue(); 00071 } 00072 00073 llvm::Function *CodeGenRoutine::getLLVMFunction() const 00074 { 00075 return SRI->getLLVMFunction(); 00076 } 00077 00078 void CodeGenRoutine::emitObjectDecl(ObjectDecl *objDecl) 00079 { 00080 Type *objTy = resolveType(objDecl->getType()); 00081 00082 if (objTy->isCompositeType()) { 00083 emitCompositeObjectDecl(objDecl); 00084 return; 00085 } 00086 00087 if (objTy->isFatAccessType()) { 00088 // If we have an initializer simply emit it and associate the temporary 00089 // with the object. Otherwise allocate a slot of the appropritate fat 00090 // pointer structure and initialize the embedded pointer to null. 00091 if (objDecl->hasInitializer()) { 00092 CValue value = emitValue(objDecl->getInitializer()); 00093 SRF->associate(objDecl, activation::Slot, value.first()); 00094 return; 00095 } 00096 00097 const llvm::StructType *fatTy; 00098 const llvm::PointerType *dataTy; 00099 llvm::Value *slot; 00100 llvm::Value *ptr; 00101 llvm::Value *null; 00102 00103 fatTy = CGT.lowerFatAccessType(cast<AccessType>(objTy)); 00104 dataTy = cast<llvm::PointerType>(fatTy->getElementType(0)); 00105 slot = SRF->createEntry(objDecl, activation::Slot, fatTy); 00106 ptr = Builder.CreateStructGEP(slot, 0); 00107 null = llvm::ConstantPointerNull::get(dataTy); 00108 Builder.CreateStore(null, ptr); 00109 return; 00110 } 00111 00112 // Otherwise, this is a simple non-composite type. Allocate a stack slot 00113 // and evaluate the initializer if present. 00114 const llvm::Type *lowTy = CGT.lowerType(objTy); 00115 llvm::Value *slot = SRF->createEntry(objDecl, activation::Slot, lowTy); 00116 if (objDecl->hasInitializer()) { 00117 CValue value = emitValue(objDecl->getInitializer()); 00118 Builder.CreateStore(value.first(), slot); 00119 } 00120 } 00121 00122 void CodeGenRoutine::emitRenamedObjectDecl(RenamedObjectDecl *objDecl) 00123 { 00124 Type *objTy = resolveType(objDecl->getType()); 00125 Expr *objExpr = objDecl->getRenamedExpr()->ignoreInjPrj(); 00126 llvm::Value *objValue; 00127 00128 // Emit a renamed object declaration as a reference to its renamed 00129 // expression and associate the result with the declaration. 00130 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(objExpr)) { 00131 // In all cases the renamed target has already been evaluated. Simply 00132 // equate the declarations. 00133 objValue = SRF->lookup(DRE->getDeclaration(), activation::Slot); 00134 } 00135 else if (objTy->isCompositeType()) 00136 objValue = emitCompositeExpr(objExpr, 0, false).first(); 00137 else 00138 objValue = emitReference(objExpr).first(); 00139 00140 SRF->associate(objDecl, activation::Slot, objValue); 00141 } 00142 00143 CValue CodeGenRoutine::emitReference(Expr *expr) 00144 { 00145 // Remove any outer inj and prj expressions. 00146 expr = expr->ignoreInjPrj(); 00147 00148 CValue result; 00149 00150 // The most common case is a reference to a declaration. 00151 if (DeclRefExpr *refExpr = dyn_cast<DeclRefExpr>(expr)) { 00152 ValueDecl *decl = refExpr->getDeclaration(); 00153 result = CValue::get(SRF->lookup(decl, activation::Slot)); 00154 } 00155 else if (IndexedArrayExpr *idxExpr = dyn_cast<IndexedArrayExpr>(expr)) 00156 result = emitIndexedArrayRef(idxExpr); 00157 else if (SelectedExpr *selExpr = dyn_cast<SelectedExpr>(expr)) 00158 result = emitSelectedRef(selExpr); 00159 else if (DereferenceExpr *derefExpr = dyn_cast<DereferenceExpr>(expr)) { 00160 // Do not dereference, just return the pointer prefix. 00161 result = emitValue(derefExpr->getPrefix()); 00162 } 00163 00164 return result; 00165 } 00166 00167 CValue CodeGenRoutine::emitValue(Expr *expr) 00168 { 00169 switch (expr->getKind()) { 00170 00171 default: 00172 if (AttribExpr *attrib = dyn_cast<AttribExpr>(expr)) 00173 return emitAttribExpr(attrib); 00174 else 00175 assert(false && "Cannot codegen expression!"); 00176 break; 00177 00178 case Ast::AST_DeclRefExpr: 00179 return emitDeclRefExpr(cast<DeclRefExpr>(expr)); 00180 00181 case Ast::AST_FunctionCallExpr: 00182 return emitFunctionCall(cast<FunctionCallExpr>(expr)); 00183 00184 case Ast::AST_DereferenceExpr: 00185 return emitDereferencedValue(cast<DereferenceExpr>(expr)); 00186 00187 case Ast::AST_InjExpr: 00188 return emitInjExpr(cast<InjExpr>(expr)); 00189 00190 case Ast::AST_PrjExpr: 00191 return emitPrjExpr(cast<PrjExpr>(expr)); 00192 00193 case Ast::AST_IntegerLiteral: 00194 return emitIntegerLiteral(cast<IntegerLiteral>(expr)); 00195 00196 case Ast::AST_IndexedArrayExpr: 00197 return emitIndexedArrayValue(cast<IndexedArrayExpr>(expr)); 00198 00199 case Ast::AST_SelectedExpr: 00200 return emitSelectedValue(cast<SelectedExpr>(expr)); 00201 00202 case Ast::AST_ConversionExpr: 00203 return emitConversionValue(cast<ConversionExpr>(expr)); 00204 00205 case Ast::AST_NullExpr: 00206 return emitNullExpr(cast<NullExpr>(expr)); 00207 00208 case Ast::AST_QualifiedExpr: 00209 return emitValue(cast<QualifiedExpr>(expr)->getOperand()); 00210 00211 case Ast::AST_AllocatorExpr: 00212 return emitAllocatorValue(cast<AllocatorExpr>(expr)); 00213 00214 case Ast::AST_DiamondExpr: 00215 return emitDefaultValue(expr->getType()); 00216 } 00217 00218 return CValue::get(0); 00219 } 00220 00221 void CodeGenRoutine::emitPragmaAssert(PragmaAssert *pragma) 00222 { 00223 CValue condition = emitValue(pragma->getCondition()); 00224 const llvm::PointerType *messageTy = CG.getInt8PtrTy(); 00225 00226 // Create basic blocks for when the assertion fires and another for the 00227 // continuation. 00228 llvm::BasicBlock *assertBB = SRF->makeBasicBlock("assert-fail"); 00229 llvm::BasicBlock *passBB = SRF->makeBasicBlock("assert-pass"); 00230 00231 // If the condition is true, the assertion does not fire. 00232 Builder.CreateCondBr(condition.first(), passBB, assertBB); 00233 00234 // Otherwise, evaluate the message if present and raise an Assert_Error 00235 // exception. 00236 Builder.SetInsertPoint(assertBB); 00237 llvm::Value *message; 00238 llvm::Value *messageLength; 00239 00240 if (pragma->hasMessage()) { 00241 BoundsEmitter emitter(*this); 00242 CValue msg = emitCompositeExpr(pragma->getMessage(), 0, true); 00243 message = msg.first(); 00244 message = Builder.CreatePointerCast(message, messageTy); 00245 messageLength = emitter.computeTotalBoundLength(Builder, msg.second()); 00246 } 00247 else { 00248 message = llvm::ConstantPointerNull::get(messageTy); 00249 messageLength = llvm::ConstantInt::get(CG.getInt32Ty(), 0); 00250 } 00251 00252 llvm::Value *fileName = CG.getModuleName(); 00253 llvm::Value *lineNum = CG.getSourceLine(pragma->getLocation()); 00254 CRT.raiseAssertionError(SRF, fileName, lineNum, message, messageLength); 00255 00256 // Switch to the continuation block. 00257 Builder.SetInsertPoint(passBB); 00258 } 00259 00260 // FIXME: We should have an AttributeEmitter to handle all attribute codegen. 00261 std::pair<llvm::Value*, llvm::Value*> 00262 CodeGenRoutine::emitRangeAttrib(RangeAttrib *attrib) 00263 { 00264 typedef std::pair<llvm::Value*, llvm::Value*> BoundPair; 00265 BoundsEmitter emitter(*this); 00266 BoundPair bounds; 00267 00268 if (ArrayRangeAttrib *arrayRange = dyn_cast<ArrayRangeAttrib>(attrib)) { 00269 CValue arrValue = emitArrayExpr(arrayRange->getPrefix(), 0, false); 00270 bounds = emitter.getBounds(Builder, arrValue.second(), 0); 00271 } 00272 else { 00273 // FIXME: This evaluation is wrong. All types should be elaborated 00274 // and the range information accessible. The following is 00275 // effectively a "re-elaboration" of the prefix type. 00276 ScalarRangeAttrib *scalarRange = cast<ScalarRangeAttrib>(attrib); 00277 DiscreteType *scalarTy = scalarRange->getType(); 00278 bounds = emitter.getScalarBounds(Builder, scalarTy); 00279 } 00280 return bounds; 00281 } 00282 00283 Type *CodeGenRoutine::resolveType(Type *type) 00284 { 00285 return const_cast<Type*>(CGT.resolveType(type)); 00286 }