CGStmt.cpp revision 7e63b8527fa0b065802fc6cb8cb6124d7c23c4a2
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- CGStmt.cpp - Emit LLVM Code from Statements ----------------------===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This contains code to emit Stmt nodes as LLVM code. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 14e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta#include "CGDebugInfo.h" 15e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta#include "CodeGenModule.h" 165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "CodeGenFunction.h" 17de7fb8413b13651fd85b7125d08b3c9ac2816d9dDaniel Dunbar#include "clang/AST/StmtVisitor.h" 18fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson#include "clang/Basic/TargetInfo.h" 19fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson#include "llvm/ADT/StringExtras.h" 2017d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson#include "llvm/InlineAsm.h" 2117d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson#include "llvm/Intrinsics.h" 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace CodeGen; 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Statement Emission 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 290912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarvoid CodeGenFunction::EmitStopPoint(const Stmt *S) { 300912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (CGDebugInfo *DI = CGM.getDebugInfo()) { 310912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar DI->setLocation(S->getLocStart()); 320912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar DI->EmitStopPoint(CurFn, Builder); 330912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar } 340912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar} 350912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitStmt(const Stmt *S) { 375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(S && "Null statement?"); 38a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar 390912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // Check if we can handle this without bothering to generate an 400912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // insert point or debug info. 410912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (EmitSimpleStmt(S)) 420912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar return; 430912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 44a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar // If we happen to be at an unreachable point just create a dummy 45a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar // basic block to hold the code. We could change parts of irgen to 46a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar // simply not generate this code, but this situation is rare and 47a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar // probably not worth the effort. 48a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar // FIXME: Verify previous performance/effort claim. 49a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar EnsureInsertPoint(); 505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 510912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // Generate a stoppoint if we are emitting debug info. 520912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(S); 53e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta 545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (S->getStmtClass()) { 555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: 561e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner // Must be an expression in a stmt context. Emit the value (to get 571e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner // side-effects) and ignore the result. 585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (const Expr *E = dyn_cast<Expr>(S)) { 591e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner if (!hasAggregateLLVMType(E->getType())) 601e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner EmitScalarExpr(E); 619b2dc287177394a8f73833e2ad4f7ca8cd6f22bbChris Lattner else if (E->getType()->isAnyComplexType()) 621e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner EmitComplexExpr(E); 631e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner else 641e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner EmitAggExpr(E, 0, false); 655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 66488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar ErrorUnsupported(S, "statement"); 675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 690ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar case Stmt::IndirectGotoStmtClass: 700ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar EmitIndirectGotoStmt(cast<IndirectGotoStmt>(*S)); break; 715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break; 735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break; 745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::DoStmtClass: EmitDoStmt(cast<DoStmt>(*S)); break; 755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::ForStmtClass: EmitForStmt(cast<ForStmt>(*S)); break; 765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break; 785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break; 79a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar 8051b09f2c528c8460b5465c676173324e44176d62Devang Patel case Stmt::SwitchStmtClass: EmitSwitchStmt(cast<SwitchStmt>(*S)); break; 81fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case Stmt::AsmStmtClass: EmitAsmStmt(cast<AsmStmt>(*S)); break; 820a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar 830a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtTryStmtClass: 8464d5d6c5903157c521af496479d06dc26032d718Anders Carlsson EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S)); 8564d5d6c5903157c521af496479d06dc26032d718Anders Carlsson break; 860a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtCatchStmtClass: 87dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson assert(0 && "@catch statements should be handled by EmitObjCAtTryStmt"); 88dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson break; 890a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtFinallyStmtClass: 9064d5d6c5903157c521af496479d06dc26032d718Anders Carlsson assert(0 && "@finally statements should be handled by EmitObjCAtTryStmt"); 910a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 920a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtThrowStmtClass: 9364d5d6c5903157c521af496479d06dc26032d718Anders Carlsson EmitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(*S)); 940a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 950a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtSynchronizedStmtClass: 9610cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattner EmitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(*S)); 970a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 983d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson case Stmt::ObjCForCollectionStmtClass: 993d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson EmitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(*S)); 1000a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1040912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarbool CodeGenFunction::EmitSimpleStmt(const Stmt *S) { 1050912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar switch (S->getStmtClass()) { 1060912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar default: return false; 1070912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::NullStmtClass: break; 1080912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break; 1090912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break; 1100912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break; 1110912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::BreakStmtClass: EmitBreakStmt(cast<BreakStmt>(*S)); break; 1120912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::ContinueStmtClass: EmitContinueStmt(cast<ContinueStmt>(*S)); break; 1130912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::DefaultStmtClass: EmitDefaultStmt(cast<DefaultStmt>(*S)); break; 1140912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::CaseStmtClass: EmitCaseStmt(cast<CaseStmt>(*S)); break; 1150912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar } 1160912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 1170912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar return true; 1180912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar} 1190912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 1203379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true, 1213379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// this captures the expression result of the last sub-statement and returns it 1223379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// (for use by the statement expression extension). 1239b65551d0b387a7597fb39356a4d8ef10046445eChris LattnerRValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, 1249b65551d0b387a7597fb39356a4d8ef10046445eChris Lattner llvm::Value *AggLoc, bool isAggVol) { 1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FIXME: handle vla's etc. 1261c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta CGDebugInfo *DI = CGM.getDebugInfo(); 1271c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta if (DI) { 1280912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EnsureInsertPoint(); 12966031a5594bc9a7dc0dc5137c3e7955f835e4639Daniel Dunbar DI->setLocation(S.getLBracLoc()); 1301c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta DI->EmitRegionStart(CurFn, Builder); 1311c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta } 1321c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta 13317d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson // Push a null stack save value. 13417d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson StackSaveValues.push_back(0); 13517d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson 1363379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner for (CompoundStmt::const_body_iterator I = S.body_begin(), 1373379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner E = S.body_end()-GetLast; I != E; ++I) 1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(*I); 139e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta 1401c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta if (DI) { 141a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar EnsureInsertPoint(); 14266031a5594bc9a7dc0dc5137c3e7955f835e4639Daniel Dunbar DI->setLocation(S.getRBracLoc()); 1431c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta DI->EmitRegionEnd(CurFn, Builder); 1441c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta } 1451c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta 14617d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson RValue RV; 14717d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson if (!GetLast) 14817d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson RV = RValue::get(0); 14917d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson else { 15017d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson // We have to special case labels here. They are statements, but when put 15117d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson // at the end of a statement expression, they yield the value of their 15217d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson // subexpression. Handle this by walking through all labels we encounter, 15317d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson // emitting them before we evaluate the subexpr. 15417d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson const Stmt *LastStmt = S.body_back(); 15517d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson while (const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) { 15617d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson EmitLabel(*LS); 15717d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson LastStmt = LS->getSubStmt(); 15817d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson } 1599b65551d0b387a7597fb39356a4d8ef10046445eChris Lattner 16017d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson EnsureInsertPoint(); 16117d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson 16217d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson RV = EmitAnyExpr(cast<Expr>(LastStmt), AggLoc); 16391d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner } 164a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar 16517d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson if (llvm::Value *V = StackSaveValues.pop_back_val()) { 16617d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson V = Builder.CreateLoad(V, "tmp"); 16717d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson 16817d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stackrestore); 16917d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson Builder.CreateCall(F, V); 17017d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson } 17117d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson 17217d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson return RV; 1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 175a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbarvoid CodeGenFunction::EmitBlock(llvm::BasicBlock *BB, bool IsFinished) { 176d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // Fall out of the current block (if necessary). 177d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(BB); 178a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar 179a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar if (IsFinished && BB->use_empty()) { 180a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar delete BB; 181a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar return; 182a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar } 183a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar 184d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar CurFn->getBasicBlockList().push_back(BB); 185d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar Builder.SetInsertPoint(BB); 186d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar} 187d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar 188d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbarvoid CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) { 189d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // Emit a branch from the current block to the target one if this 190d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // was a real block. If this was just a fall-through block after a 191d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // terminator, don't emit it. 192d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); 193d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar 194d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar if (!CurBB || CurBB->getTerminator()) { 195d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // If there is no insert point or the previous block is already 196d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // terminated, don't touch it. 1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, create a fall-through branch. 199d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar Builder.CreateBr(Target); 2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2015e08ad3cc62ab94649959ae227a9a411a729bf49Daniel Dunbar 2025e08ad3cc62ab94649959ae227a9a411a729bf49Daniel Dunbar Builder.ClearInsertionPoint(); 2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 20591d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattnervoid CodeGenFunction::EmitLabel(const LabelStmt &S) { 2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S); 2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(NextBB); 20891d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner} 20991d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner 21091d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner 21191d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattnervoid CodeGenFunction::EmitLabelStmt(const LabelStmt &S) { 21291d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner EmitLabel(S); 2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getSubStmt()); 2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitGotoStmt(const GotoStmt &S) { 217a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar // FIXME: Implement goto out in @try or @catch blocks. 218a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar if (!ObjCEHStack.empty()) { 219a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar CGM.ErrorUnsupported(&S, "goto inside an Obj-C exception block"); 220a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar return; 221a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar } 222a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar 2237e63b8527fa0b065802fc6cb8cb6124d7c23c4a2Anders Carlsson for (int i = 0; i < StackSaveValues.size(); i++) { 2247e63b8527fa0b065802fc6cb8cb6124d7c23c4a2Anders Carlsson if (StackSaveValues[i]) { 2257e63b8527fa0b065802fc6cb8cb6124d7c23c4a2Anders Carlsson CGM.ErrorUnsupported(&S, "goto inside scope with VLA"); 2267e63b8527fa0b065802fc6cb8cb6124d7c23c4a2Anders Carlsson return; 2277e63b8527fa0b065802fc6cb8cb6124d7c23c4a2Anders Carlsson } 228eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson } 229eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson 2300912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // If this code is reachable then emit a stop point (if generating 2310912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // debug info). We have to do this ourselves because we are on the 2320912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // "simple" statement path. 2330912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (HaveInsertPoint()) 2340912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(&S); 235d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(getBasicBlockForLabel(S.getLabel())); 2365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2380ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbarvoid CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) { 239a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar // FIXME: Implement indirect goto in @try or @catch blocks. 240a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar if (!ObjCEHStack.empty()) { 241a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar CGM.ErrorUnsupported(&S, "goto inside an Obj-C exception block"); 242a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar return; 243a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar } 244a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar 2450ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // Emit initial switch which will be patched up later by 2460ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // EmitIndirectSwitches(). We need a default dest, so we use the 2470ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // current BB, but this is overwritten. 2480ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar llvm::Value *V = Builder.CreatePtrToInt(EmitScalarExpr(S.getTarget()), 2490ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar llvm::Type::Int32Ty, 2500ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar "addr"); 2510ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar llvm::SwitchInst *I = Builder.CreateSwitch(V, Builder.GetInsertBlock()); 2520ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar IndirectSwitches.push_back(I); 2530ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar 254a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar // Clear the insertion point to indicate we are in unreachable code. 255a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar Builder.ClearInsertionPoint(); 2560ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar} 2570ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar 25862b72f642207ba2ba433d686df924dc9594e9897Chris Lattnervoid CodeGenFunction::EmitIfStmt(const IfStmt &S) { 2595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.4.1: The first substatement is executed if the expression compares 2605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // unequal to 0. The condition must be a scalar type. 2615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2629bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // If the condition constant folds and can be elided, try to avoid emitting 2639bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // the condition and the dead arm of the if/else. 26431a0984b5cb4af99d2407c0f25bf5af68df681c6Chris Lattner if (int Cond = ConstantFoldsToSimpleInteger(S.getCond())) { 26562b72f642207ba2ba433d686df924dc9594e9897Chris Lattner // Figure out which block (then or else) is executed. 26662b72f642207ba2ba433d686df924dc9594e9897Chris Lattner const Stmt *Executed = S.getThen(), *Skipped = S.getElse(); 2679bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner if (Cond == -1) // Condition false? 26862b72f642207ba2ba433d686df924dc9594e9897Chris Lattner std::swap(Executed, Skipped); 2699bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner 27062b72f642207ba2ba433d686df924dc9594e9897Chris Lattner // If the skipped block has no labels in it, just emit the executed block. 27162b72f642207ba2ba433d686df924dc9594e9897Chris Lattner // This avoids emitting dead code and simplifies the CFG substantially. 2729bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner if (!ContainsLabel(Skipped)) { 27362b72f642207ba2ba433d686df924dc9594e9897Chris Lattner if (Executed) 27462b72f642207ba2ba433d686df924dc9594e9897Chris Lattner EmitStmt(Executed); 27562b72f642207ba2ba433d686df924dc9594e9897Chris Lattner return; 27662b72f642207ba2ba433d686df924dc9594e9897Chris Lattner } 27762b72f642207ba2ba433d686df924dc9594e9897Chris Lattner } 2789bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner 2799bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // Otherwise, the condition did not fold, or we couldn't elide it. Just emit 2809bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // the conditional branch. 281781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar llvm::BasicBlock *ThenBlock = createBasicBlock("if.then"); 282781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar llvm::BasicBlock *ContBlock = createBasicBlock("if.end"); 283781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar llvm::BasicBlock *ElseBlock = ContBlock; 2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getElse()) 285781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar ElseBlock = createBasicBlock("if.else"); 286781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar EmitBranchOnBoolExpr(S.getCond(), ThenBlock, ElseBlock); 2875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the 'then' code. 2895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ThenBlock); 2905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getThen()); 291d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(ContBlock); 2925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the 'else' code if present. 2945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (const Stmt *Else = S.getElse()) { 2955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ElseBlock); 2965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(Else); 297d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(ContBlock); 2985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the continuation block for code after the if. 301c22d665ede76f70228055d638a087f4bd438292dDaniel Dunbar EmitBlock(ContBlock, true); 3025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitWhileStmt(const WhileStmt &S) { 3055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the header for the loop, insert it, which will create an uncond br to 3065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // it. 3079615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *LoopHeader = createBasicBlock("while.cond"); 3085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(LoopHeader); 3095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the conditional in the while header. C99 6.8.5.1: The evaluation 3115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // of the controlling expression takes place before each execution of the loop 3125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // body. 3135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 3142c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel 3152c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel // while(1) is common, avoid extra exit blocks. Be sure 3165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // to correctly handle break/continue though. 3172c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel bool EmitBoolCondBranch = true; 3182c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) 3192c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (C->isOne()) 3202c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel EmitBoolCondBranch = false; 3215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Create an exit block for when the condition fails, create a block for the 3235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // body of the loop. 324c22d665ede76f70228055d638a087f4bd438292dDaniel Dunbar llvm::BasicBlock *ExitBlock = createBasicBlock("while.end"); 3259615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *LoopBody = createBasicBlock("while.body"); 3265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // As long as the condition is true, go to the loop body. 3282c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (EmitBoolCondBranch) 3292c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock); 33031a0984b5cb4af99d2407c0f25bf5af68df681c6Chris Lattner 331da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 332e21269bcb732afa70386fdd4c95d22bc2ed943b1Anders Carlsson BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader, 333e21269bcb732afa70386fdd4c95d22bc2ed943b1Anders Carlsson ObjCEHStack.size())); 3345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the loop body. 3365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(LoopBody); 3375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getBody()); 338da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 339da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.pop_back(); 3405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Cycle to the condition. 342d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(LoopHeader); 3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the exit block. 345c22d665ede76f70228055d638a087f4bd438292dDaniel Dunbar EmitBlock(ExitBlock, true); 3462c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel 3472c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel // If LoopHeader is a simple forwarding block then eliminate it. 3482c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (!EmitBoolCondBranch 3492c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel && &LoopHeader->front() == LoopHeader->getTerminator()) { 3502c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel LoopHeader->replaceAllUsesWith(LoopBody); 3512c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel LoopHeader->getTerminator()->eraseFromParent(); 3522c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel LoopHeader->eraseFromParent(); 3532c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel } 3545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitDoStmt(const DoStmt &S) { 3575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the body for the loop, insert it, which will create an uncond br to 3585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // it. 3599615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *LoopBody = createBasicBlock("do.body"); 3609615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *AfterDo = createBasicBlock("do.end"); 3615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(LoopBody); 362da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 3639615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *DoCond = createBasicBlock("do.cond"); 364da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 365da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 366e21269bcb732afa70386fdd4c95d22bc2ed943b1Anders Carlsson BreakContinueStack.push_back(BreakContinue(AfterDo, DoCond, 367e21269bcb732afa70386fdd4c95d22bc2ed943b1Anders Carlsson ObjCEHStack.size())); 3685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the body of the loop into the block. 3705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getBody()); 3715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 372da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.pop_back(); 373da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 374da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner EmitBlock(DoCond); 375da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 3765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5.2: "The evaluation of the controlling expression takes place 3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // after each execution of the loop body." 3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the conditional in the while header. 3805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5p2/p4: The first substatement is executed if the expression 3815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // compares unequal to 0. The condition must be a scalar type. 3825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 38305f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 38405f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // "do {} while (0)" is common in macros, avoid extra blocks. Be sure 38505f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // to correctly handle break/continue though. 38605f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel bool EmitBoolCondBranch = true; 38705f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) 38805f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (C->isZero()) 38905f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel EmitBoolCondBranch = false; 39005f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 3915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // As long as the condition is true, iterate the loop. 39205f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (EmitBoolCondBranch) 39305f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo); 3945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the exit block. 396c22d665ede76f70228055d638a087f4bd438292dDaniel Dunbar EmitBlock(AfterDo, true); 39705f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 39805f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // If DoCond is a simple forwarding block then eliminate it. 39905f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (!EmitBoolCondBranch && &DoCond->front() == DoCond->getTerminator()) { 40005f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel DoCond->replaceAllUsesWith(AfterDo); 40105f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel DoCond->getTerminator()->eraseFromParent(); 40205f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel DoCond->eraseFromParent(); 40305f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel } 4045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitForStmt(const ForStmt &S) { 4075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FIXME: What do we do if the increment (f.e.) contains a stmt expression, 4085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // which contains a continue/break? 409da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 4105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the first part before the loop. 4115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getInit()) 4125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getInit()); 4135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Start the loop with a block that tests the condition. 4159615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 4169615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 417da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 4185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(CondBlock); 4195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the condition if present. If not, treat it as a non-zero-constant 4215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // according to 6.8.5.3p2, aka, true. 4225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getCond()) { 42331a0984b5cb4af99d2407c0f25bf5af68df681c6Chris Lattner // As long as the condition is true, iterate the loop. 4249615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 42531a0984b5cb4af99d2407c0f25bf5af68df681c6Chris Lattner 4265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5p2/p4: The first substatement is executed if the expression 4275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // compares unequal to 0. The condition must be a scalar type. 42831a0984b5cb4af99d2407c0f25bf5af68df681c6Chris Lattner EmitBranchOnBoolExpr(S.getCond(), ForBody, AfterFor); 4295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ForBody); 4315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 4325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Treat it as a non-zero constant. Don't even create a new block for the 4335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // body, just fall into it. 4345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 436da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // If the for loop doesn't have an increment we can just use the 437da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // condition as the continue block. 438da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner llvm::BasicBlock *ContinueBlock; 439da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner if (S.getInc()) 4409615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar ContinueBlock = createBasicBlock("for.inc"); 441da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner else 442da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner ContinueBlock = CondBlock; 443da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 444da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 445e21269bcb732afa70386fdd4c95d22bc2ed943b1Anders Carlsson BreakContinueStack.push_back(BreakContinue(AfterFor, ContinueBlock, 446e21269bcb732afa70386fdd4c95d22bc2ed943b1Anders Carlsson ObjCEHStack.size())); 447da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 4485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the condition is true, execute the body of the for stmt. 4495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getBody()); 450da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 451da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.pop_back(); 452da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 4535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If there is an increment, emit it next. 454ad12b6d643aba6c36f5cec4c9beb4977a12eace4Daniel Dunbar if (S.getInc()) { 455ad12b6d643aba6c36f5cec4c9beb4977a12eace4Daniel Dunbar EmitBlock(ContinueBlock); 456883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner EmitStmt(S.getInc()); 457ad12b6d643aba6c36f5cec4c9beb4977a12eace4Daniel Dunbar } 4585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Finally, branch back up to the condition for the next iteration. 460d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(CondBlock); 4615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 462da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Emit the fall-through block. 463c22d665ede76f70228055d638a087f4bd438292dDaniel Dunbar EmitBlock(AfterFor, true); 4645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 46629e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbarvoid CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) { 46729e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar if (RV.isScalar()) { 46829e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar Builder.CreateStore(RV.getScalarVal(), ReturnValue); 46929e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } else if (RV.isAggregate()) { 47029e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar EmitAggregateCopy(ReturnValue, RV.getAggregateAddr(), Ty); 47129e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } else { 47229e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false); 47329e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } 474d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(ReturnBlock); 47529e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar} 47629e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar 4775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand 4785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// if the function returns void, or may be missing one if the function returns 4795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// non-void. Fun stuff :). 4805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { 4817e63b8527fa0b065802fc6cb8cb6124d7c23c4a2Anders Carlsson for (int i = 0; i < StackSaveValues.size(); i++) { 4827e63b8527fa0b065802fc6cb8cb6124d7c23c4a2Anders Carlsson if (StackSaveValues[i]) { 4837e63b8527fa0b065802fc6cb8cb6124d7c23c4a2Anders Carlsson CGM.ErrorUnsupported(&S, "return inside scope with VLA"); 4847e63b8527fa0b065802fc6cb8cb6124d7c23c4a2Anders Carlsson return; 4857e63b8527fa0b065802fc6cb8cb6124d7c23c4a2Anders Carlsson } 486eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson } 487eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson 4885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the result value, even if unused, to evalute the side effects. 4895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const Expr *RV = S.getRetValue(); 4905ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar 4915ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // FIXME: Clean this up by using an LValue for ReturnTemp, 4925ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // EmitStoreThroughLValue, and EmitAnyExpr. 4935ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar if (!ReturnValue) { 4945ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // Make sure not to return anything, but evaluate the expression 4955ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // for side effects. 4965ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar if (RV) 497144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman EmitAnyExpr(RV); 4985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else if (RV == 0) { 4995ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // Do nothing (return value is left uninitialized) 5004b0029d5f8742760981a3bd58004f75454090a61Chris Lattner } else if (!hasAggregateLLVMType(RV->getType())) { 5015ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar Builder.CreateStore(EmitScalarExpr(RV), ReturnValue); 5029b2dc287177394a8f73833e2ad4f7ca8cd6f22bbChris Lattner } else if (RV->getType()->isAnyComplexType()) { 5035ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar EmitComplexExprIntoAddr(RV, ReturnValue, false); 5045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 5055ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar EmitAggExpr(RV, ReturnValue, false); 5065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 507144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman 508898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar if (!ObjCEHStack.empty()) { 509898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar for (ObjCEHStackType::reverse_iterator i = ObjCEHStack.rbegin(), 510898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar e = ObjCEHStack.rend(); i != e; ++i) { 51155e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar llvm::BasicBlock *ReturnPad = createBasicBlock("return.pad"); 512898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar EmitJumpThroughFinally(*i, ReturnPad); 513898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar EmitBlock(ReturnPad); 514898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar } 515898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar } 516898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar 517d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(ReturnBlock); 5185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 5195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitDeclStmt(const DeclStmt &S) { 521e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek for (DeclStmt::const_decl_iterator I = S.decl_begin(), E = S.decl_end(); 522e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek I != E; ++I) 523e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek EmitDecl(**I); 5246fa5f0943a84233b2e1ec9716eae55643225bfd4Chris Lattner} 525da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 5260912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarvoid CodeGenFunction::EmitBreakStmt(const BreakStmt &S) { 527da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!"); 528da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 5290912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // FIXME: Implement break in @try or @catch blocks. 530e21269bcb732afa70386fdd4c95d22bc2ed943b1Anders Carlsson if (ObjCEHStack.size() != BreakContinueStack.back().EHStackSize) { 531eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson CGM.ErrorUnsupported(&S, "break inside an Obj-C exception block"); 5320912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar return; 5330912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar } 5340912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 535eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson if (StackSaveValues.back()) { 536eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson CGM.ErrorUnsupported(&S, "break inside scope with VLA"); 537eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson return; 538eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson } 539eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson 5400912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // If this code is reachable then emit a stop point (if generating 5410912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // debug info). We have to do this ourselves because we are on the 5420912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // "simple" statement path. 5430912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (HaveInsertPoint()) 5440912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(&S); 545da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock; 546d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(Block); 547da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner} 548da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 5490912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarvoid CodeGenFunction::EmitContinueStmt(const ContinueStmt &S) { 550da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 551da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 5520912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // FIXME: Implement continue in @try or @catch blocks. 553e21269bcb732afa70386fdd4c95d22bc2ed943b1Anders Carlsson if (ObjCEHStack.size() != BreakContinueStack.back().EHStackSize) { 5540912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar CGM.ErrorUnsupported(&S, "continue inside an Obj-C exception block"); 5550912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar return; 5560912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar } 5570912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 558eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson if (StackSaveValues.back()) { 559eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson CGM.ErrorUnsupported(&S, "continue inside scope with VLA"); 560eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson return; 561eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson } 562eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson 5630912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // If this code is reachable then emit a stop point (if generating 5640912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // debug info). We have to do this ourselves because we are on the 5650912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // "simple" statement path. 5660912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (HaveInsertPoint()) 5670912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(&S); 568da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock; 569d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(Block); 570da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner} 57151b09f2c528c8460b5465c676173324e44176d62Devang Patel 572c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// EmitCaseStmtRange - If case statement range is not too big then 573c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// add multiple cases to switch instruction, one for each value within 574c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// the range. If range is too big then emit "if" condition check. 575c049e4f406a7f7179eba98659044a32508e53289Devang Patelvoid CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) { 5764efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar assert(S.getRHS() && "Expected RHS value in CaseStmt"); 577c049e4f406a7f7179eba98659044a32508e53289Devang Patel 57851fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson llvm::APSInt LHS = S.getLHS()->EvaluateAsInt(getContext()); 57951fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson llvm::APSInt RHS = S.getRHS()->EvaluateAsInt(getContext()); 5804efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar 58116f23570999cac1fa13597386938450843003840Daniel Dunbar // Emit the code for this case. We do this first to make sure it is 58216f23570999cac1fa13597386938450843003840Daniel Dunbar // properly chained from our predecessor before generating the 58316f23570999cac1fa13597386938450843003840Daniel Dunbar // switch machinery to enter this block. 584f84dcda7e2ab2f6d5be5a8c52d22ef4c442dd762Daniel Dunbar EmitBlock(createBasicBlock("sw.bb")); 58516f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *CaseDest = Builder.GetInsertBlock(); 58616f23570999cac1fa13597386938450843003840Daniel Dunbar EmitStmt(S.getSubStmt()); 58716f23570999cac1fa13597386938450843003840Daniel Dunbar 5884efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar // If range is empty, do nothing. 5894efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar if (LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS)) 5904efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar return; 591c049e4f406a7f7179eba98659044a32508e53289Devang Patel 592c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::APInt Range = RHS - LHS; 59316f23570999cac1fa13597386938450843003840Daniel Dunbar // FIXME: parameters such as this should not be hardcoded. 594c049e4f406a7f7179eba98659044a32508e53289Devang Patel if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) { 595c049e4f406a7f7179eba98659044a32508e53289Devang Patel // Range is small enough to add multiple switch instruction cases. 5964efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar for (unsigned i = 0, e = Range.getZExtValue() + 1; i != e; ++i) { 5972d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel SwitchInsn->addCase(llvm::ConstantInt::get(LHS), CaseDest); 5982d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel LHS++; 5992d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel } 600c049e4f406a7f7179eba98659044a32508e53289Devang Patel return; 601c049e4f406a7f7179eba98659044a32508e53289Devang Patel } 602c049e4f406a7f7179eba98659044a32508e53289Devang Patel 60316f23570999cac1fa13597386938450843003840Daniel Dunbar // The range is too big. Emit "if" condition into a new block, 60416f23570999cac1fa13597386938450843003840Daniel Dunbar // making sure to save and restore the current insertion point. 60516f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *RestoreBB = Builder.GetInsertBlock(); 60616f23570999cac1fa13597386938450843003840Daniel Dunbar 60716f23570999cac1fa13597386938450843003840Daniel Dunbar // Push this test onto the chain of range checks (which terminates 60816f23570999cac1fa13597386938450843003840Daniel Dunbar // in the default basic block). The switch's default will be changed 60916f23570999cac1fa13597386938450843003840Daniel Dunbar // to the top of this chain after switch emission is complete. 61016f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *FalseDest = CaseRangeBlock; 61155e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar CaseRangeBlock = createBasicBlock("sw.caserange"); 61216f23570999cac1fa13597386938450843003840Daniel Dunbar 61316f23570999cac1fa13597386938450843003840Daniel Dunbar CurFn->getBasicBlockList().push_back(CaseRangeBlock); 61416f23570999cac1fa13597386938450843003840Daniel Dunbar Builder.SetInsertPoint(CaseRangeBlock); 615c049e4f406a7f7179eba98659044a32508e53289Devang Patel 616c049e4f406a7f7179eba98659044a32508e53289Devang Patel // Emit range check. 617c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::Value *Diff = 6184efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar Builder.CreateSub(SwitchInsn->getCondition(), llvm::ConstantInt::get(LHS), 6194efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar "tmp"); 620c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::Value *Cond = 621c049e4f406a7f7179eba98659044a32508e53289Devang Patel Builder.CreateICmpULE(Diff, llvm::ConstantInt::get(Range), "tmp"); 622c049e4f406a7f7179eba98659044a32508e53289Devang Patel Builder.CreateCondBr(Cond, CaseDest, FalseDest); 623c049e4f406a7f7179eba98659044a32508e53289Devang Patel 62416f23570999cac1fa13597386938450843003840Daniel Dunbar // Restore the appropriate insertion point. 625a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar if (RestoreBB) 626a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar Builder.SetInsertPoint(RestoreBB); 627a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar else 628a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar Builder.ClearInsertionPoint(); 629c049e4f406a7f7179eba98659044a32508e53289Devang Patel} 6302d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel 631c049e4f406a7f7179eba98659044a32508e53289Devang Patelvoid CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { 632c049e4f406a7f7179eba98659044a32508e53289Devang Patel if (S.getRHS()) { 633c049e4f406a7f7179eba98659044a32508e53289Devang Patel EmitCaseStmtRange(S); 634c049e4f406a7f7179eba98659044a32508e53289Devang Patel return; 635c049e4f406a7f7179eba98659044a32508e53289Devang Patel } 636c049e4f406a7f7179eba98659044a32508e53289Devang Patel 637f84dcda7e2ab2f6d5be5a8c52d22ef4c442dd762Daniel Dunbar EmitBlock(createBasicBlock("sw.bb")); 638c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::BasicBlock *CaseDest = Builder.GetInsertBlock(); 63951fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson llvm::APSInt CaseVal = S.getLHS()->EvaluateAsInt(getContext()); 64055e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar SwitchInsn->addCase(llvm::ConstantInt::get(CaseVal), CaseDest); 64151b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getSubStmt()); 64251b09f2c528c8460b5465c676173324e44176d62Devang Patel} 64351b09f2c528c8460b5465c676173324e44176d62Devang Patel 64451b09f2c528c8460b5465c676173324e44176d62Devang Patelvoid CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) { 64516f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest(); 64655e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar assert(DefaultBlock->empty() && 64755e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar "EmitDefaultStmt: Default block already defined?"); 64816f23570999cac1fa13597386938450843003840Daniel Dunbar EmitBlock(DefaultBlock); 64951b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getSubStmt()); 65051b09f2c528c8460b5465c676173324e44176d62Devang Patel} 65151b09f2c528c8460b5465c676173324e44176d62Devang Patel 65251b09f2c528c8460b5465c676173324e44176d62Devang Patelvoid CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { 65351b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::Value *CondV = EmitScalarExpr(S.getCond()); 65451b09f2c528c8460b5465c676173324e44176d62Devang Patel 65551b09f2c528c8460b5465c676173324e44176d62Devang Patel // Handle nested switch statements. 65651b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::SwitchInst *SavedSwitchInsn = SwitchInsn; 657c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::BasicBlock *SavedCRBlock = CaseRangeBlock; 65851b09f2c528c8460b5465c676173324e44176d62Devang Patel 65916f23570999cac1fa13597386938450843003840Daniel Dunbar // Create basic block to hold stuff that comes after switch 66016f23570999cac1fa13597386938450843003840Daniel Dunbar // statement. We also need to create a default block now so that 66116f23570999cac1fa13597386938450843003840Daniel Dunbar // explicit case ranges tests can have a place to jump to on 66216f23570999cac1fa13597386938450843003840Daniel Dunbar // failure. 66355e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar llvm::BasicBlock *NextBlock = createBasicBlock("sw.epilog"); 66455e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar llvm::BasicBlock *DefaultBlock = createBasicBlock("sw.default"); 66516f23570999cac1fa13597386938450843003840Daniel Dunbar SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock); 66616f23570999cac1fa13597386938450843003840Daniel Dunbar CaseRangeBlock = DefaultBlock; 66751b09f2c528c8460b5465c676173324e44176d62Devang Patel 6680912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // Clear the insertion point to indicate we are in unreachable code. 6690912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar Builder.ClearInsertionPoint(); 670d28a80d64616b66c91d28bb4c08ca2d8c594de4eEli Friedman 671e9b8c0a38549692f1b8f688c05c35442fc620865Devang Patel // All break statements jump to NextBlock. If BreakContinueStack is non empty 672e9b8c0a38549692f1b8f688c05c35442fc620865Devang Patel // then reuse last ContinueBlock. 67351b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::BasicBlock *ContinueBlock = NULL; 67451b09f2c528c8460b5465c676173324e44176d62Devang Patel if (!BreakContinueStack.empty()) 67551b09f2c528c8460b5465c676173324e44176d62Devang Patel ContinueBlock = BreakContinueStack.back().ContinueBlock; 676e21269bcb732afa70386fdd4c95d22bc2ed943b1Anders Carlsson BreakContinueStack.push_back(BreakContinue(NextBlock, ContinueBlock, 677e21269bcb732afa70386fdd4c95d22bc2ed943b1Anders Carlsson ObjCEHStack.size())); 67851b09f2c528c8460b5465c676173324e44176d62Devang Patel 67951b09f2c528c8460b5465c676173324e44176d62Devang Patel // Emit switch body. 68051b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getBody()); 68151b09f2c528c8460b5465c676173324e44176d62Devang Patel BreakContinueStack.pop_back(); 68251b09f2c528c8460b5465c676173324e44176d62Devang Patel 68316f23570999cac1fa13597386938450843003840Daniel Dunbar // Update the default block in case explicit case range tests have 68416f23570999cac1fa13597386938450843003840Daniel Dunbar // been chained on top. 68516f23570999cac1fa13597386938450843003840Daniel Dunbar SwitchInsn->setSuccessor(0, CaseRangeBlock); 686c049e4f406a7f7179eba98659044a32508e53289Devang Patel 68716f23570999cac1fa13597386938450843003840Daniel Dunbar // If a default was never emitted then reroute any jumps to it and 68816f23570999cac1fa13597386938450843003840Daniel Dunbar // discard. 68916f23570999cac1fa13597386938450843003840Daniel Dunbar if (!DefaultBlock->getParent()) { 69016f23570999cac1fa13597386938450843003840Daniel Dunbar DefaultBlock->replaceAllUsesWith(NextBlock); 69116f23570999cac1fa13597386938450843003840Daniel Dunbar delete DefaultBlock; 69216f23570999cac1fa13597386938450843003840Daniel Dunbar } 69316f23570999cac1fa13597386938450843003840Daniel Dunbar 69416f23570999cac1fa13597386938450843003840Daniel Dunbar // Emit continuation. 695c22d665ede76f70228055d638a087f4bd438292dDaniel Dunbar EmitBlock(NextBlock, true); 69651b09f2c528c8460b5465c676173324e44176d62Devang Patel 69751b09f2c528c8460b5465c676173324e44176d62Devang Patel SwitchInsn = SavedSwitchInsn; 698c049e4f406a7f7179eba98659044a32508e53289Devang Patel CaseRangeBlock = SavedCRBlock; 69951b09f2c528c8460b5465c676173324e44176d62Devang Patel} 700fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 701ce179ab4358c152164899c032302d8b0e81982b6Anders Carlssonstatic std::string ConvertAsmString(const AsmStmt& S, bool &Failed) 702ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson{ 703ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson // FIXME: No need to create new std::string here, we could just make sure 704ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson // that we don't read past the end of the string data. 705ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson std::string str(S.getAsmString()->getStrData(), 706ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson S.getAsmString()->getByteLength()); 707ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson const char *Start = str.c_str(); 708ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 709ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson unsigned NumOperands = S.getNumOutputs() + S.getNumInputs(); 710ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson bool IsSimple = S.isSimple(); 711281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar Failed = false; 712281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar 713fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson static unsigned AsmCounter = 0; 714fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson AsmCounter++; 715fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Result; 7162abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson if (IsSimple) { 7172abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson while (*Start) { 7182abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson switch (*Start) { 7192abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson default: 7202abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Result += *Start; 7212abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson break; 7222abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson case '$': 7232abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Result += "$$"; 7242abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson break; 7252abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 7262abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Start++; 7272abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 7282abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson 7292abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson return Result; 7302abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 731fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 732fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson while (*Start) { 733fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson switch (*Start) { 734fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson default: 735fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += *Start; 736fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 737fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '$': 738fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += "$$"; 739fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 740fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '%': 741fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Escaped character 742fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Start++; 743fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (!*Start) { 744fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // FIXME: This should be caught during Sema. 745fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(0 && "Trailing '%' in asm string."); 746fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 747fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 748fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson char EscapedChar = *Start; 749fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (EscapedChar == '%') { 750fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Escaped percentage sign. 751fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += '%'; 752345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner } else if (EscapedChar == '=') { 753fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Generate an unique ID. 754fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += llvm::utostr(AsmCounter); 755fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else if (isdigit(EscapedChar)) { 756fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // %n - Assembler operand n 757fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson char *End; 758fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson unsigned long n = strtoul(Start, &End, 10); 759fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (Start == End) { 760fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // FIXME: This should be caught during Sema. 761fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(0 && "Missing operand!"); 762fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else if (n >= NumOperands) { 763fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // FIXME: This should be caught during Sema. 764fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(0 && "Operand number out of range!"); 765fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 766fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 767fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += '$' + llvm::utostr(n); 7687695f70bbd3e4d42adaa1ef2ff5e1b9ab3d9c345Lauro Ramos Venancio Start = End - 1; 7692abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } else if (isalpha(EscapedChar)) { 7702abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson char *End; 7712abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson 7722abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson unsigned long n = strtoul(Start + 1, &End, 10); 7732abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson if (Start == End) { 7742abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson // FIXME: This should be caught during Sema. 7752abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson assert(0 && "Missing operand!"); 7762abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } else if (n >= NumOperands) { 7772abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson // FIXME: This should be caught during Sema. 7782abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson assert(0 && "Operand number out of range!"); 7792abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 7802abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson 7812abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Result += "${" + llvm::utostr(n) + ':' + EscapedChar + '}'; 7827695f70bbd3e4d42adaa1ef2ff5e1b9ab3d9c345Lauro Ramos Venancio Start = End - 1; 783ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } else if (EscapedChar == '[') { 784ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson std::string SymbolicName; 785ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 786ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson Start++; 787ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 788ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson while (*Start && *Start != ']') { 789ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson SymbolicName += *Start; 790ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 791ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson Start++; 792ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } 793ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 794ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson if (!Start) { 795ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson // FIXME: Should be caught by sema. 796ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson assert(0 && "Could not parse symbolic name"); 797ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } 798ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 799ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson assert(*Start == ']' && "Error parsing symbolic name"); 800ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 801ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson int Index = -1; 802ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 803ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson // Check if this is an output operand. 804ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson for (unsigned i = 0; i < S.getNumOutputs(); i++) { 805ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson if (S.getOutputName(i) == SymbolicName) { 806ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson Index = i; 807ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson break; 808ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } 809ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } 810ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 811ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson if (Index == -1) { 812ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson for (unsigned i = 0; i < S.getNumInputs(); i++) { 813ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson if (S.getInputName(i) == SymbolicName) { 814ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson Index = S.getNumOutputs() + i; 815ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } 816ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } 817ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } 818ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 819ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson assert(Index != -1 && "Did not find right operand!"); 820ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 821ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson Result += '$' + llvm::utostr(Index); 822ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 823fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 824281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar Failed = true; 825281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar return ""; 826fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 827fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 828fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Start++; 829fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 830fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 831fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson return Result; 832fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 833fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 834a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venanciostatic std::string SimplifyConstraint(const char* Constraint, 835a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio TargetInfo &Target) { 836fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Result; 837fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 838fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson while (*Constraint) { 839fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson switch (*Constraint) { 840fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson default: 841a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio Result += Target.convertConstraint(*Constraint); 842fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 843fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Ignore these 844fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '*': 845fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '?': 846fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '!': 847fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 848fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case 'g': 849fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += "imr"; 850fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 851fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 852fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 853fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraint++; 854fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 855fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 856fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson return Result; 857fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 858fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 859fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlssonvoid CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { 860281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar bool Failed; 861fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string AsmString = 862ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson ConvertAsmString(S, Failed); 863281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar 864281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar if (Failed) { 865281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar ErrorUnsupported(&S, "asm string"); 866281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar return; 867281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar } 868fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 869fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Constraints; 870fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 871fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::Value *ResultAddr = 0; 872fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const llvm::Type *ResultType = llvm::Type::VoidTy; 873fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 874fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::vector<const llvm::Type*> ArgTypes; 875fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::vector<llvm::Value*> Args; 876f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 877f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // Keep track of inout constraints. 878f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::string InOutConstraints; 879f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::vector<llvm::Value*> InOutArgs; 880f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::vector<const llvm::Type*> InOutArgTypes; 881fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 882fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) { 883fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string OutputConstraint(S.getOutputConstraint(i)->getStrData(), 884fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.getOutputConstraint(i)->getByteLength()); 885fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 886fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson TargetInfo::ConstraintInfo Info; 887fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson bool result = Target.validateOutputConstraint(OutputConstraint.c_str(), 888fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Info); 8893304e55f613ce34d9a14c3aaf06f5949408b3092Chris Lattner assert(result && "Failed to parse output constraint"); result=result; 890fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 891fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Simplify the output constraint. 892a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1, Target); 893fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 894fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson LValue Dest = EmitLValue(S.getOutputExpr(i)); 895fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const llvm::Type *DestValueType = 896fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson cast<llvm::PointerType>(Dest.getAddress()->getType())->getElementType(); 897fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 898fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // If the first output operand is not a memory dest, we'll 899fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // make it the return value. 900fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (i == 0 && !(Info & TargetInfo::CI_AllowsMemory) && 901d79a726dc3c8af61b486948c97a183c7fe5b0179Dan Gohman DestValueType->isSingleValueType()) { 902fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ResultAddr = Dest.getAddress(); 903fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ResultType = DestValueType; 904fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += "=" + OutputConstraint; 905fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 906fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ArgTypes.push_back(Dest.getAddress()->getType()); 907cad3ab611ebd3bee3ce6395d649640047f904cdeAnders Carlsson Args.push_back(Dest.getAddress()); 908fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (i != 0) 909fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 910f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Constraints += "=*"; 911fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += OutputConstraint; 912f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 913f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 914f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson if (Info & TargetInfo::CI_ReadWrite) { 915f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // FIXME: This code should be shared with the code that handles inputs. 916f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutConstraints += ','; 917f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 918f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson const Expr *InputExpr = S.getOutputExpr(i); 919f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson llvm::Value *Arg; 920f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson if ((Info & TargetInfo::CI_AllowsRegister) || 921f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson !(Info & TargetInfo::CI_AllowsMemory)) { 922d79a726dc3c8af61b486948c97a183c7fe5b0179Dan Gohman if (ConvertType(InputExpr->getType())->isSingleValueType()) { 923f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Arg = EmitScalarExpr(InputExpr); 924f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } else { 92562b72f642207ba2ba433d686df924dc9594e9897Chris Lattner ErrorUnsupported(&S, 92662b72f642207ba2ba433d686df924dc9594e9897Chris Lattner "asm statement passing multiple-value types as inputs"); 927f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 928f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } else { 929f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson LValue Dest = EmitLValue(InputExpr); 930f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Arg = Dest.getAddress(); 931f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutConstraints += '*'; 932f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 933f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 934f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutArgTypes.push_back(Arg->getType()); 935f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutArgs.push_back(Arg); 936f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutConstraints += OutputConstraint; 937f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 938fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 939fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 940fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson unsigned NumConstraints = S.getNumOutputs() + S.getNumInputs(); 941fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 942fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) { 943fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const Expr *InputExpr = S.getInputExpr(i); 944fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 945fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string InputConstraint(S.getInputConstraint(i)->getStrData(), 946fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.getInputConstraint(i)->getByteLength()); 947fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 948fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson TargetInfo::ConstraintInfo Info; 949fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson bool result = Target.validateInputConstraint(InputConstraint.c_str(), 9503304e55f613ce34d9a14c3aaf06f5949408b3092Chris Lattner NumConstraints, Info); 9513304e55f613ce34d9a14c3aaf06f5949408b3092Chris Lattner assert(result && "Failed to parse input constraint"); result=result; 952fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 953fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (i != 0 || S.getNumOutputs() > 0) 954fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 955fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 956fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Simplify the input constraint. 957a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio InputConstraint = SimplifyConstraint(InputConstraint.c_str(), Target); 958fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 959fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::Value *Arg; 960fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 961fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if ((Info & TargetInfo::CI_AllowsRegister) || 962fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson !(Info & TargetInfo::CI_AllowsMemory)) { 963d79a726dc3c8af61b486948c97a183c7fe5b0179Dan Gohman if (ConvertType(InputExpr->getType())->isSingleValueType()) { 964fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Arg = EmitScalarExpr(InputExpr); 965fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 96662b72f642207ba2ba433d686df924dc9594e9897Chris Lattner ErrorUnsupported(&S, 96762b72f642207ba2ba433d686df924dc9594e9897Chris Lattner "asm statement passing multiple-value types as inputs"); 968fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 969fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 970fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson LValue Dest = EmitLValue(InputExpr); 971fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Arg = Dest.getAddress(); 972fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += '*'; 973fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 974fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 975fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ArgTypes.push_back(Arg->getType()); 976fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Args.push_back(Arg); 977fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += InputConstraint; 978fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 979fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 980f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // Append the "input" part of inout constraints last. 981f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { 982f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson ArgTypes.push_back(InOutArgTypes[i]); 983f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Args.push_back(InOutArgs[i]); 984f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 985f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Constraints += InOutConstraints; 986f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 987fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Clobbers 988fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) { 989fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Clobber(S.getClobber(i)->getStrData(), 990fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.getClobber(i)->getByteLength()); 991fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 992fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Clobber = Target.getNormalizedGCCRegisterName(Clobber.c_str()); 993fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 994ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson if (i != 0 || NumConstraints != 0) 995fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 996ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson 997ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson Constraints += "~{"; 998fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += Clobber; 999ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson Constraints += '}'; 1000fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 1001fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1002fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Add machine specific clobbers 1003fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (const char *C = Target.getClobbers()) { 1004fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (!Constraints.empty()) 1005fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 1006fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += C; 1007fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 1008f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 1009fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const llvm::FunctionType *FTy = 1010fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::FunctionType::get(ResultType, ArgTypes, false); 1011fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1012fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::InlineAsm *IA = 1013fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::InlineAsm::get(FTy, AsmString, Constraints, 1014fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.isVolatile() || S.getNumOutputs() == 0); 1015fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::Value *Result = Builder.CreateCall(IA, Args.begin(), Args.end(), ""); 10161e692ace08959399794363e77499b73da5494af9Eli Friedman if (ResultAddr) // FIXME: volatility 1017fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Builder.CreateStore(Result, ResultAddr); 1018fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 1019