CGStmt.cpp revision e4ea1f42c97a436df3e0ae8e129e6bc624ee6790
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/InlineAsm.h" 20fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson#include "llvm/ADT/StringExtras.h" 215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace CodeGen; 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Statement Emission 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitStmt(const Stmt *S) { 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(S && "Null statement?"); 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 31e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta // Generate stoppoints if we are emitting debug info. 32e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta // Beginning of a Compound Statement (e.g. an opening '{') does not produce 33e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta // executable code. So do not generate a stoppoint for that. 34e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta CGDebugInfo *DI = CGM.getDebugInfo(); 35e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta if (DI && S->getStmtClass() != Stmt::CompoundStmtClass) { 36e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta if (S->getLocStart().isValid()) { 37e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta DI->setLocation(S->getLocStart()); 38e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta } 39e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta 40e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta DI->EmitStopPoint(CurFn, Builder); 41e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta } 42e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta 435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (S->getStmtClass()) { 445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: 451e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner // Must be an expression in a stmt context. Emit the value (to get 461e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner // side-effects) and ignore the result. 475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (const Expr *E = dyn_cast<Expr>(S)) { 481e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner if (!hasAggregateLLVMType(E->getType())) 491e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner EmitScalarExpr(E); 509b2dc287177394a8f73833e2ad4f7ca8cd6f22bbChris Lattner else if (E->getType()->isAnyComplexType()) 511e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner EmitComplexExpr(E); 521e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner else 531e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner EmitAggExpr(E, 0, false); 545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 55488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar ErrorUnsupported(S, "statement"); 565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::NullStmtClass: break; 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break; 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break; 615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break; 620ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar case Stmt::IndirectGotoStmtClass: 630ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar EmitIndirectGotoStmt(cast<IndirectGotoStmt>(*S)); break; 645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break; 665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break; 675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::DoStmtClass: EmitDoStmt(cast<DoStmt>(*S)); break; 685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::ForStmtClass: EmitForStmt(cast<ForStmt>(*S)); break; 695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break; 715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break; 72da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 73a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar case Stmt::BreakStmtClass: 74a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar // FIXME: Implement break in @try or @catch blocks. 75a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar if (!ObjCEHStack.empty()) { 76a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar CGM.ErrorUnsupported(S, "continue inside an Obj-C exception block"); 77a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar return; 78a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar } 79a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar EmitBreakStmt(); 80a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar break; 81a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar 82a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar case Stmt::ContinueStmtClass: 83a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar // FIXME: Implement continue in @try or @catch blocks. 84a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar if (!ObjCEHStack.empty()) { 85a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar CGM.ErrorUnsupported(S, "continue inside an Obj-C exception block"); 86a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar return; 87a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar } 88a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar EmitContinueStmt(); 89a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar break; 90a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar 9151b09f2c528c8460b5465c676173324e44176d62Devang Patel case Stmt::SwitchStmtClass: EmitSwitchStmt(cast<SwitchStmt>(*S)); break; 9251b09f2c528c8460b5465c676173324e44176d62Devang Patel case Stmt::DefaultStmtClass: EmitDefaultStmt(cast<DefaultStmt>(*S)); break; 9351b09f2c528c8460b5465c676173324e44176d62Devang Patel case Stmt::CaseStmtClass: EmitCaseStmt(cast<CaseStmt>(*S)); break; 94fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case Stmt::AsmStmtClass: EmitAsmStmt(cast<AsmStmt>(*S)); break; 950a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar 960a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtTryStmtClass: 9764d5d6c5903157c521af496479d06dc26032d718Anders Carlsson EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S)); 9864d5d6c5903157c521af496479d06dc26032d718Anders Carlsson break; 990a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtCatchStmtClass: 100dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson assert(0 && "@catch statements should be handled by EmitObjCAtTryStmt"); 101dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson break; 1020a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtFinallyStmtClass: 10364d5d6c5903157c521af496479d06dc26032d718Anders Carlsson assert(0 && "@finally statements should be handled by EmitObjCAtTryStmt"); 1040a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 1050a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtThrowStmtClass: 10664d5d6c5903157c521af496479d06dc26032d718Anders Carlsson EmitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(*S)); 1070a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 1080a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtSynchronizedStmtClass: 1090a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar ErrorUnsupported(S, "@synchronized statement"); 1100a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 1113d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson case Stmt::ObjCForCollectionStmtClass: 1123d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson EmitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(*S)); 1130a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1173379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true, 1183379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// this captures the expression result of the last sub-statement and returns it 1193379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// (for use by the statement expression extension). 1209b65551d0b387a7597fb39356a4d8ef10046445eChris LattnerRValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, 1219b65551d0b387a7597fb39356a4d8ef10046445eChris Lattner llvm::Value *AggLoc, bool isAggVol) { 1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FIXME: handle vla's etc. 1231c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta CGDebugInfo *DI = CGM.getDebugInfo(); 1241c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta if (DI) { 125345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner if (S.getLBracLoc().isValid()) 1261c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta DI->setLocation(S.getLBracLoc()); 1271c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta DI->EmitRegionStart(CurFn, Builder); 1281c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta } 1291c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta 1303379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner for (CompoundStmt::const_body_iterator I = S.body_begin(), 1313379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner E = S.body_end()-GetLast; I != E; ++I) 1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(*I); 133e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta 1341c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta if (DI) { 135345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner if (S.getRBracLoc().isValid()) 1361c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta DI->setLocation(S.getRBracLoc()); 1371c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta DI->EmitRegionEnd(CurFn, Builder); 1381c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta } 1391c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta 1403379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner if (!GetLast) 1413379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner return RValue::get(0); 1429b65551d0b387a7597fb39356a4d8ef10046445eChris Lattner 14391d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner // We have to special case labels here. They are statements, but when put at 14491d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner // the end of a statement expression, they yield the value of their 14591d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner // subexpression. Handle this by walking through all labels we encounter, 14691d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner // emitting them before we evaluate the subexpr. 14791d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner const Stmt *LastStmt = S.body_back(); 14891d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner while (const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) { 14991d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner EmitLabel(*LS); 15091d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner LastStmt = LS->getSubStmt(); 15191d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner } 15291d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner 15391d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner return EmitAnyExpr(cast<Expr>(LastStmt), AggLoc); 1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitBlock(llvm::BasicBlock *BB) { 1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit a branch from this block to the next one if this was a real block. If 1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // this was just a fall-through block after a terminator, don't emit it. 1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::BasicBlock *LastBB = Builder.GetInsertBlock(); 1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (LastBB->getTerminator()) { 1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the previous block is already terminated, don't touch it. 16316f23570999cac1fa13597386938450843003840Daniel Dunbar } else if (LastBB->empty() && isDummyBlock(LastBB)) { 1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the last block was an empty placeholder, remove it now. 1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // TODO: cache and reuse these. 16616f23570999cac1fa13597386938450843003840Daniel Dunbar LastBB->eraseFromParent(); 1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, create a fall-through branch. 1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Builder.CreateBr(BB); 1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CurFn->getBasicBlockList().push_back(BB); 1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Builder.SetInsertPoint(BB); 1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 17591d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattnervoid CodeGenFunction::EmitLabel(const LabelStmt &S) { 1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S); 1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(NextBB); 17891d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner} 17991d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner 18091d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner 18191d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattnervoid CodeGenFunction::EmitLabelStmt(const LabelStmt &S) { 18291d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner EmitLabel(S); 1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getSubStmt()); 1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitGotoStmt(const GotoStmt &S) { 187a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar // FIXME: Implement goto out in @try or @catch blocks. 188a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar if (!ObjCEHStack.empty()) { 189a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar CGM.ErrorUnsupported(&S, "goto inside an Obj-C exception block"); 190a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar return; 191a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar } 192a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar 1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Builder.CreateBr(getBasicBlockForLabel(S.getLabel())); 1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit a block after the branch so that dead code after a goto has some place 1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // to go. 197984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif Builder.SetInsertPoint(llvm::BasicBlock::Create("", CurFn)); 1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2000ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbarvoid CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) { 201a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar // FIXME: Implement indirect goto in @try or @catch blocks. 202a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar if (!ObjCEHStack.empty()) { 203a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar CGM.ErrorUnsupported(&S, "goto inside an Obj-C exception block"); 204a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar return; 205a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar } 206a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar 2070ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // Emit initial switch which will be patched up later by 2080ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // EmitIndirectSwitches(). We need a default dest, so we use the 2090ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // current BB, but this is overwritten. 2100ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar llvm::Value *V = Builder.CreatePtrToInt(EmitScalarExpr(S.getTarget()), 2110ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar llvm::Type::Int32Ty, 2120ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar "addr"); 2130ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar llvm::SwitchInst *I = Builder.CreateSwitch(V, Builder.GetInsertBlock()); 2140ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar IndirectSwitches.push_back(I); 2150ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar 2160ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // Emit a block after the branch so that dead code after a goto has some place 2170ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // to go. 2180ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar Builder.SetInsertPoint(llvm::BasicBlock::Create("", CurFn)); 2190ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar} 2200ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar 2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitIfStmt(const IfStmt &S) { 2220ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // FIXME: It would probably be nice for us to skip emission of if 2230ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // (0) code here. 2240ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar 2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.4.1: The first substatement is executed if the expression compares 2265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // unequal to 0. The condition must be a scalar type. 2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 229984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *ContBlock = llvm::BasicBlock::Create("ifend"); 230984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *ThenBlock = llvm::BasicBlock::Create("ifthen"); 2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::BasicBlock *ElseBlock = ContBlock; 2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getElse()) 234984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif ElseBlock = llvm::BasicBlock::Create("ifelse"); 2355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Insert the conditional branch. 2375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Builder.CreateCondBr(BoolCondVal, ThenBlock, ElseBlock); 2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the 'then' code. 2405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ThenBlock); 2415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getThen()); 242d9363c3a80168283b3da518b4e17f545a6246857Devang Patel llvm::BasicBlock *BB = Builder.GetInsertBlock(); 243d9363c3a80168283b3da518b4e17f545a6246857Devang Patel if (isDummyBlock(BB)) { 244d9363c3a80168283b3da518b4e17f545a6246857Devang Patel BB->eraseFromParent(); 245d9363c3a80168283b3da518b4e17f545a6246857Devang Patel Builder.SetInsertPoint(ThenBlock); 246345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner } else { 247d9363c3a80168283b3da518b4e17f545a6246857Devang Patel Builder.CreateBr(ContBlock); 248345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner } 2495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the 'else' code if present. 2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (const Stmt *Else = S.getElse()) { 2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ElseBlock); 2535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(Else); 254d9363c3a80168283b3da518b4e17f545a6246857Devang Patel llvm::BasicBlock *BB = Builder.GetInsertBlock(); 255d9363c3a80168283b3da518b4e17f545a6246857Devang Patel if (isDummyBlock(BB)) { 256d9363c3a80168283b3da518b4e17f545a6246857Devang Patel BB->eraseFromParent(); 257d9363c3a80168283b3da518b4e17f545a6246857Devang Patel Builder.SetInsertPoint(ElseBlock); 258345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner } else { 259d9363c3a80168283b3da518b4e17f545a6246857Devang Patel Builder.CreateBr(ContBlock); 260345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner } 2615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the continuation block for code after the if. 2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ContBlock); 2655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitWhileStmt(const WhileStmt &S) { 2685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the header for the loop, insert it, which will create an uncond br to 2695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // it. 270984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *LoopHeader = llvm::BasicBlock::Create("whilecond"); 2715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(LoopHeader); 2725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the conditional in the while header. C99 6.8.5.1: The evaluation 2745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // of the controlling expression takes place before each execution of the loop 2755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // body. 2765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 2772c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel 2782c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel // while(1) is common, avoid extra exit blocks. Be sure 2795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // to correctly handle break/continue though. 2802c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel bool EmitBoolCondBranch = true; 2812c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) 2822c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (C->isOne()) 2832c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel EmitBoolCondBranch = false; 2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Create an exit block for when the condition fails, create a block for the 2865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // body of the loop. 287984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *ExitBlock = llvm::BasicBlock::Create("whileexit"); 288984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *LoopBody = llvm::BasicBlock::Create("whilebody"); 2895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // As long as the condition is true, go to the loop body. 2912c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (EmitBoolCondBranch) 2922c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock); 293da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 294da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 295da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader)); 2965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the loop body. 2985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(LoopBody); 2995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getBody()); 300da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 301da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.pop_back(); 3025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Cycle to the condition. 3045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Builder.CreateBr(LoopHeader); 3055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the exit block. 3075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ExitBlock); 3082c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel 3092c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel // If LoopHeader is a simple forwarding block then eliminate it. 3102c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (!EmitBoolCondBranch 3112c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel && &LoopHeader->front() == LoopHeader->getTerminator()) { 3122c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel LoopHeader->replaceAllUsesWith(LoopBody); 3132c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel LoopHeader->getTerminator()->eraseFromParent(); 3142c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel LoopHeader->eraseFromParent(); 3152c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel } 3165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitDoStmt(const DoStmt &S) { 3195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the body for the loop, insert it, which will create an uncond br to 3205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // it. 321984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *LoopBody = llvm::BasicBlock::Create("dobody"); 322984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *AfterDo = llvm::BasicBlock::Create("afterdo"); 3235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(LoopBody); 324da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 325984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *DoCond = llvm::BasicBlock::Create("docond"); 326da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 327da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 328da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.push_back(BreakContinue(AfterDo, DoCond)); 3295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the body of the loop into the block. 3315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getBody()); 3325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 333da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.pop_back(); 334da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 335da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner EmitBlock(DoCond); 336da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 3375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5.2: "The evaluation of the controlling expression takes place 3385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // after each execution of the loop body." 3395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the conditional in the while header. 3415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5p2/p4: The first substatement is executed if the expression 3425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // compares unequal to 0. The condition must be a scalar type. 3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 34405f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 34505f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // "do {} while (0)" is common in macros, avoid extra blocks. Be sure 34605f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // to correctly handle break/continue though. 34705f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel bool EmitBoolCondBranch = true; 34805f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) 34905f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (C->isZero()) 35005f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel EmitBoolCondBranch = false; 35105f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 3525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // As long as the condition is true, iterate the loop. 35305f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (EmitBoolCondBranch) 35405f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo); 3555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the exit block. 3575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(AfterDo); 35805f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 35905f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // If DoCond is a simple forwarding block then eliminate it. 36005f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (!EmitBoolCondBranch && &DoCond->front() == DoCond->getTerminator()) { 36105f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel DoCond->replaceAllUsesWith(AfterDo); 36205f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel DoCond->getTerminator()->eraseFromParent(); 36305f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel DoCond->eraseFromParent(); 36405f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel } 3655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitForStmt(const ForStmt &S) { 3685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FIXME: What do we do if the increment (f.e.) contains a stmt expression, 3695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // which contains a continue/break? 370da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // TODO: We could keep track of whether the loop body contains any 371da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // break/continue statements and not create unnecessary blocks (like 372da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // "afterfor" for a condless loop) if it doesn't. 373da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 3745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the first part before the loop. 3755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getInit()) 3765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getInit()); 3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Start the loop with a block that tests the condition. 379984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *CondBlock = llvm::BasicBlock::Create("forcond"); 380984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *AfterFor = llvm::BasicBlock::Create("afterfor"); 381da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 3825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(CondBlock); 3835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the condition if present. If not, treat it as a non-zero-constant 3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // according to 6.8.5.3p2, aka, true. 3865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getCond()) { 3875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5p2/p4: The first substatement is executed if the expression 3885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // compares unequal to 0. The condition must be a scalar type. 3895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 3905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // As long as the condition is true, iterate the loop. 392984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif llvm::BasicBlock *ForBody = llvm::BasicBlock::Create("forbody"); 3935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Builder.CreateCondBr(BoolCondVal, ForBody, AfterFor); 3945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ForBody); 3955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 3965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Treat it as a non-zero constant. Don't even create a new block for the 3975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // body, just fall into it. 3985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 3995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 400da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // If the for loop doesn't have an increment we can just use the 401da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // condition as the continue block. 402da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner llvm::BasicBlock *ContinueBlock; 403da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner if (S.getInc()) 404984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif ContinueBlock = llvm::BasicBlock::Create("forinc"); 405da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner else 406da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner ContinueBlock = CondBlock; 407da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 408da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 409da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.push_back(BreakContinue(AfterFor, ContinueBlock)); 410da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 4115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the condition is true, execute the body of the for stmt. 4125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getBody()); 413da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 414da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner BreakContinueStack.pop_back(); 415da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 4165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If there is an increment, emit it next. 417ad12b6d643aba6c36f5cec4c9beb4977a12eace4Daniel Dunbar if (S.getInc()) { 418ad12b6d643aba6c36f5cec4c9beb4977a12eace4Daniel Dunbar EmitBlock(ContinueBlock); 419883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner EmitStmt(S.getInc()); 420ad12b6d643aba6c36f5cec4c9beb4977a12eace4Daniel Dunbar } 4215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Finally, branch back up to the condition for the next iteration. 4235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Builder.CreateBr(CondBlock); 4245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 425da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Emit the fall-through block. 426da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner EmitBlock(AfterFor); 4275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 42929e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbarvoid CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) { 43029e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar if (RV.isScalar()) { 43129e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar Builder.CreateStore(RV.getScalarVal(), ReturnValue); 43229e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } else if (RV.isAggregate()) { 43329e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar EmitAggregateCopy(ReturnValue, RV.getAggregateAddr(), Ty); 43429e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } else { 43529e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false); 43629e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } 43729e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar Builder.CreateBr(ReturnBlock); 43829e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar 43929e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar // Emit a block after the branch so that dead code after a return has some 44029e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar // place to go. 44129e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar EmitBlock(llvm::BasicBlock::Create()); 44229e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar} 44329e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar 4445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand 4455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// if the function returns void, or may be missing one if the function returns 4465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// non-void. Fun stuff :). 4475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { 4485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the result value, even if unused, to evalute the side effects. 4495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const Expr *RV = S.getRetValue(); 4505ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar 4515ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // FIXME: Clean this up by using an LValue for ReturnTemp, 4525ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // EmitStoreThroughLValue, and EmitAnyExpr. 4535ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar if (!ReturnValue) { 4545ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // Make sure not to return anything, but evaluate the expression 4555ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // for side effects. 4565ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar if (RV) 457144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman EmitAnyExpr(RV); 4585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else if (RV == 0) { 4595ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // Do nothing (return value is left uninitialized) 4604b0029d5f8742760981a3bd58004f75454090a61Chris Lattner } else if (!hasAggregateLLVMType(RV->getType())) { 4615ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar Builder.CreateStore(EmitScalarExpr(RV), ReturnValue); 4629b2dc287177394a8f73833e2ad4f7ca8cd6f22bbChris Lattner } else if (RV->getType()->isAnyComplexType()) { 4635ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar EmitComplexExprIntoAddr(RV, ReturnValue, false); 4645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 4655ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar EmitAggExpr(RV, ReturnValue, false); 4665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 467144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman 468898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar if (!ObjCEHStack.empty()) { 469898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar for (ObjCEHStackType::reverse_iterator i = ObjCEHStack.rbegin(), 470898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar e = ObjCEHStack.rend(); i != e; ++i) { 471898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar llvm::BasicBlock *ReturnPad = llvm::BasicBlock::Create("return.pad"); 472898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar EmitJumpThroughFinally(*i, ReturnPad); 473898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar EmitBlock(ReturnPad); 474898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar } 475898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar } 476898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar 4775ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar Builder.CreateBr(ReturnBlock); 4785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit a block after the branch so that dead code after a return has some 4805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // place to go. 481984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif EmitBlock(llvm::BasicBlock::Create()); 4825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitDeclStmt(const DeclStmt &S) { 485e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek for (DeclStmt::const_decl_iterator I = S.decl_begin(), E = S.decl_end(); 486e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek I != E; ++I) 487e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek EmitDecl(**I); 4886fa5f0943a84233b2e1ec9716eae55643225bfd4Chris Lattner} 489da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 490da13870e99fe33934b2122f06528a5063f78ae4cChris Lattnervoid CodeGenFunction::EmitBreakStmt() { 491da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!"); 492da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 493da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock; 494da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner Builder.CreateBr(Block); 495984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif EmitBlock(llvm::BasicBlock::Create()); 496da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner} 497da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 498da13870e99fe33934b2122f06528a5063f78ae4cChris Lattnervoid CodeGenFunction::EmitContinueStmt() { 499da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 500da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 501da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock; 502da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner Builder.CreateBr(Block); 503984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif EmitBlock(llvm::BasicBlock::Create()); 504da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner} 50551b09f2c528c8460b5465c676173324e44176d62Devang Patel 506c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// EmitCaseStmtRange - If case statement range is not too big then 507c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// add multiple cases to switch instruction, one for each value within 508c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// the range. If range is too big then emit "if" condition check. 509c049e4f406a7f7179eba98659044a32508e53289Devang Patelvoid CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) { 5104efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar assert(S.getRHS() && "Expected RHS value in CaseStmt"); 511c049e4f406a7f7179eba98659044a32508e53289Devang Patel 5124efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar llvm::APSInt LHS = S.getLHS()->getIntegerConstantExprValue(getContext()); 5134efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar llvm::APSInt RHS = S.getRHS()->getIntegerConstantExprValue(getContext()); 5144efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar 51516f23570999cac1fa13597386938450843003840Daniel Dunbar // Emit the code for this case. We do this first to make sure it is 51616f23570999cac1fa13597386938450843003840Daniel Dunbar // properly chained from our predecessor before generating the 51716f23570999cac1fa13597386938450843003840Daniel Dunbar // switch machinery to enter this block. 51816f23570999cac1fa13597386938450843003840Daniel Dunbar StartBlock("sw.bb"); 51916f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *CaseDest = Builder.GetInsertBlock(); 52016f23570999cac1fa13597386938450843003840Daniel Dunbar EmitStmt(S.getSubStmt()); 52116f23570999cac1fa13597386938450843003840Daniel Dunbar 5224efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar // If range is empty, do nothing. 5234efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar if (LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS)) 5244efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar return; 525c049e4f406a7f7179eba98659044a32508e53289Devang Patel 526c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::APInt Range = RHS - LHS; 52716f23570999cac1fa13597386938450843003840Daniel Dunbar // FIXME: parameters such as this should not be hardcoded. 528c049e4f406a7f7179eba98659044a32508e53289Devang Patel if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) { 529c049e4f406a7f7179eba98659044a32508e53289Devang Patel // Range is small enough to add multiple switch instruction cases. 5304efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar for (unsigned i = 0, e = Range.getZExtValue() + 1; i != e; ++i) { 5312d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel SwitchInsn->addCase(llvm::ConstantInt::get(LHS), CaseDest); 5322d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel LHS++; 5332d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel } 534c049e4f406a7f7179eba98659044a32508e53289Devang Patel return; 535c049e4f406a7f7179eba98659044a32508e53289Devang Patel } 536c049e4f406a7f7179eba98659044a32508e53289Devang Patel 53716f23570999cac1fa13597386938450843003840Daniel Dunbar // The range is too big. Emit "if" condition into a new block, 53816f23570999cac1fa13597386938450843003840Daniel Dunbar // making sure to save and restore the current insertion point. 53916f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *RestoreBB = Builder.GetInsertBlock(); 54016f23570999cac1fa13597386938450843003840Daniel Dunbar 54116f23570999cac1fa13597386938450843003840Daniel Dunbar // Push this test onto the chain of range checks (which terminates 54216f23570999cac1fa13597386938450843003840Daniel Dunbar // in the default basic block). The switch's default will be changed 54316f23570999cac1fa13597386938450843003840Daniel Dunbar // to the top of this chain after switch emission is complete. 54416f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *FalseDest = CaseRangeBlock; 54516f23570999cac1fa13597386938450843003840Daniel Dunbar CaseRangeBlock = llvm::BasicBlock::Create("sw.caserange"); 54616f23570999cac1fa13597386938450843003840Daniel Dunbar 54716f23570999cac1fa13597386938450843003840Daniel Dunbar CurFn->getBasicBlockList().push_back(CaseRangeBlock); 54816f23570999cac1fa13597386938450843003840Daniel Dunbar Builder.SetInsertPoint(CaseRangeBlock); 549c049e4f406a7f7179eba98659044a32508e53289Devang Patel 550c049e4f406a7f7179eba98659044a32508e53289Devang Patel // Emit range check. 551c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::Value *Diff = 5524efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar Builder.CreateSub(SwitchInsn->getCondition(), llvm::ConstantInt::get(LHS), 5534efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar "tmp"); 554c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::Value *Cond = 555c049e4f406a7f7179eba98659044a32508e53289Devang Patel Builder.CreateICmpULE(Diff, llvm::ConstantInt::get(Range), "tmp"); 556c049e4f406a7f7179eba98659044a32508e53289Devang Patel Builder.CreateCondBr(Cond, CaseDest, FalseDest); 557c049e4f406a7f7179eba98659044a32508e53289Devang Patel 55816f23570999cac1fa13597386938450843003840Daniel Dunbar // Restore the appropriate insertion point. 55916f23570999cac1fa13597386938450843003840Daniel Dunbar Builder.SetInsertPoint(RestoreBB); 560c049e4f406a7f7179eba98659044a32508e53289Devang Patel} 5612d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel 562c049e4f406a7f7179eba98659044a32508e53289Devang Patelvoid CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { 563c049e4f406a7f7179eba98659044a32508e53289Devang Patel if (S.getRHS()) { 564c049e4f406a7f7179eba98659044a32508e53289Devang Patel EmitCaseStmtRange(S); 565c049e4f406a7f7179eba98659044a32508e53289Devang Patel return; 566c049e4f406a7f7179eba98659044a32508e53289Devang Patel } 567c049e4f406a7f7179eba98659044a32508e53289Devang Patel 568c049e4f406a7f7179eba98659044a32508e53289Devang Patel StartBlock("sw.bb"); 569c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::BasicBlock *CaseDest = Builder.GetInsertBlock(); 5704efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar llvm::APSInt CaseVal = S.getLHS()->getIntegerConstantExprValue(getContext()); 5714efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar SwitchInsn->addCase(llvm::ConstantInt::get(CaseVal), 5724efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar CaseDest); 57351b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getSubStmt()); 57451b09f2c528c8460b5465c676173324e44176d62Devang Patel} 57551b09f2c528c8460b5465c676173324e44176d62Devang Patel 57651b09f2c528c8460b5465c676173324e44176d62Devang Patelvoid CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) { 57716f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest(); 57816f23570999cac1fa13597386938450843003840Daniel Dunbar assert(DefaultBlock->empty() && "EmitDefaultStmt: Default block already defined?"); 57916f23570999cac1fa13597386938450843003840Daniel Dunbar EmitBlock(DefaultBlock); 58051b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getSubStmt()); 58151b09f2c528c8460b5465c676173324e44176d62Devang Patel} 58251b09f2c528c8460b5465c676173324e44176d62Devang Patel 58351b09f2c528c8460b5465c676173324e44176d62Devang Patelvoid CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { 58451b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::Value *CondV = EmitScalarExpr(S.getCond()); 58551b09f2c528c8460b5465c676173324e44176d62Devang Patel 58651b09f2c528c8460b5465c676173324e44176d62Devang Patel // Handle nested switch statements. 58751b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::SwitchInst *SavedSwitchInsn = SwitchInsn; 588c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::BasicBlock *SavedCRBlock = CaseRangeBlock; 58951b09f2c528c8460b5465c676173324e44176d62Devang Patel 59016f23570999cac1fa13597386938450843003840Daniel Dunbar // Create basic block to hold stuff that comes after switch 59116f23570999cac1fa13597386938450843003840Daniel Dunbar // statement. We also need to create a default block now so that 59216f23570999cac1fa13597386938450843003840Daniel Dunbar // explicit case ranges tests can have a place to jump to on 59316f23570999cac1fa13597386938450843003840Daniel Dunbar // failure. 59416f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *NextBlock = llvm::BasicBlock::Create("sw.epilog"); 59516f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *DefaultBlock = llvm::BasicBlock::Create("sw.default"); 59616f23570999cac1fa13597386938450843003840Daniel Dunbar SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock); 59716f23570999cac1fa13597386938450843003840Daniel Dunbar CaseRangeBlock = DefaultBlock; 59851b09f2c528c8460b5465c676173324e44176d62Devang Patel 599d28a80d64616b66c91d28bb4c08ca2d8c594de4eEli Friedman // Create basic block for body of switch 60016f23570999cac1fa13597386938450843003840Daniel Dunbar StartBlock("sw.body"); 601d28a80d64616b66c91d28bb4c08ca2d8c594de4eEli Friedman 602e9b8c0a38549692f1b8f688c05c35442fc620865Devang Patel // All break statements jump to NextBlock. If BreakContinueStack is non empty 603e9b8c0a38549692f1b8f688c05c35442fc620865Devang Patel // then reuse last ContinueBlock. 60451b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::BasicBlock *ContinueBlock = NULL; 60551b09f2c528c8460b5465c676173324e44176d62Devang Patel if (!BreakContinueStack.empty()) 60651b09f2c528c8460b5465c676173324e44176d62Devang Patel ContinueBlock = BreakContinueStack.back().ContinueBlock; 60751b09f2c528c8460b5465c676173324e44176d62Devang Patel BreakContinueStack.push_back(BreakContinue(NextBlock, ContinueBlock)); 60851b09f2c528c8460b5465c676173324e44176d62Devang Patel 60951b09f2c528c8460b5465c676173324e44176d62Devang Patel // Emit switch body. 61051b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getBody()); 61151b09f2c528c8460b5465c676173324e44176d62Devang Patel BreakContinueStack.pop_back(); 61251b09f2c528c8460b5465c676173324e44176d62Devang Patel 61316f23570999cac1fa13597386938450843003840Daniel Dunbar // Update the default block in case explicit case range tests have 61416f23570999cac1fa13597386938450843003840Daniel Dunbar // been chained on top. 61516f23570999cac1fa13597386938450843003840Daniel Dunbar SwitchInsn->setSuccessor(0, CaseRangeBlock); 616c049e4f406a7f7179eba98659044a32508e53289Devang Patel 61716f23570999cac1fa13597386938450843003840Daniel Dunbar // If a default was never emitted then reroute any jumps to it and 61816f23570999cac1fa13597386938450843003840Daniel Dunbar // discard. 61916f23570999cac1fa13597386938450843003840Daniel Dunbar if (!DefaultBlock->getParent()) { 62016f23570999cac1fa13597386938450843003840Daniel Dunbar DefaultBlock->replaceAllUsesWith(NextBlock); 62116f23570999cac1fa13597386938450843003840Daniel Dunbar delete DefaultBlock; 62216f23570999cac1fa13597386938450843003840Daniel Dunbar } 62316f23570999cac1fa13597386938450843003840Daniel Dunbar 62416f23570999cac1fa13597386938450843003840Daniel Dunbar // Emit continuation. 62516f23570999cac1fa13597386938450843003840Daniel Dunbar EmitBlock(NextBlock); 62651b09f2c528c8460b5465c676173324e44176d62Devang Patel 62751b09f2c528c8460b5465c676173324e44176d62Devang Patel SwitchInsn = SavedSwitchInsn; 628c049e4f406a7f7179eba98659044a32508e53289Devang Patel CaseRangeBlock = SavedCRBlock; 62951b09f2c528c8460b5465c676173324e44176d62Devang Patel} 630fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 631345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattnerstatic std::string ConvertAsmString(const char *Start, unsigned NumOperands, 632345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner bool IsSimple) { 633fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson static unsigned AsmCounter = 0; 634fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson AsmCounter++; 635fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Result; 6362abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson if (IsSimple) { 6372abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson while (*Start) { 6382abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson switch (*Start) { 6392abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson default: 6402abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Result += *Start; 6412abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson break; 6422abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson case '$': 6432abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Result += "$$"; 6442abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson break; 6452abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 6462abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Start++; 6472abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 6482abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson 6492abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson return Result; 6502abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 651fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 652fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson while (*Start) { 653fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson switch (*Start) { 654fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson default: 655fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += *Start; 656fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 657fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '$': 658fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += "$$"; 659fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 660fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '%': 661fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Escaped character 662fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Start++; 663fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (!*Start) { 664fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // FIXME: This should be caught during Sema. 665fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(0 && "Trailing '%' in asm string."); 666fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 667fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 668fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson char EscapedChar = *Start; 669fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (EscapedChar == '%') { 670fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Escaped percentage sign. 671fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += '%'; 672345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner } else if (EscapedChar == '=') { 673fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Generate an unique ID. 674fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += llvm::utostr(AsmCounter); 675fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else if (isdigit(EscapedChar)) { 676fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // %n - Assembler operand n 677fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson char *End; 678fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson unsigned long n = strtoul(Start, &End, 10); 679fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (Start == End) { 680fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // FIXME: This should be caught during Sema. 681fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(0 && "Missing operand!"); 682fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else if (n >= NumOperands) { 683fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // FIXME: This should be caught during Sema. 684fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(0 && "Operand number out of range!"); 685fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 686fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 687fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += '$' + llvm::utostr(n); 6887695f70bbd3e4d42adaa1ef2ff5e1b9ab3d9c345Lauro Ramos Venancio Start = End - 1; 6892abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } else if (isalpha(EscapedChar)) { 6902abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson char *End; 6912abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson 6922abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson unsigned long n = strtoul(Start + 1, &End, 10); 6932abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson if (Start == End) { 6942abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson // FIXME: This should be caught during Sema. 6952abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson assert(0 && "Missing operand!"); 6962abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } else if (n >= NumOperands) { 6972abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson // FIXME: This should be caught during Sema. 6982abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson assert(0 && "Operand number out of range!"); 6992abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 7002abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson 7012abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Result += "${" + llvm::utostr(n) + ':' + EscapedChar + '}'; 7027695f70bbd3e4d42adaa1ef2ff5e1b9ab3d9c345Lauro Ramos Venancio Start = End - 1; 703fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 704fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(0 && "Unhandled asm escaped character!"); 705fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 706fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 707fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Start++; 708fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 709fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 710fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson return Result; 711fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 712fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 713a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venanciostatic std::string SimplifyConstraint(const char* Constraint, 714a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio TargetInfo &Target) { 715fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Result; 716fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 717fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson while (*Constraint) { 718fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson switch (*Constraint) { 719fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson default: 720a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio Result += Target.convertConstraint(*Constraint); 721fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 722fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Ignore these 723fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '*': 724fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '?': 725fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '!': 726fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 727fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case 'g': 728fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += "imr"; 729fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 730fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 731fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 732fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraint++; 733fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 734fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 735fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson return Result; 736fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 737fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 738fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlssonvoid CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { 739fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string AsmString = 740fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ConvertAsmString(std::string(S.getAsmString()->getStrData(), 741fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.getAsmString()->getByteLength()).c_str(), 7422abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson S.getNumOutputs() + S.getNumInputs(), S.isSimple()); 743fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 744fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Constraints; 745fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 746fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::Value *ResultAddr = 0; 747fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const llvm::Type *ResultType = llvm::Type::VoidTy; 748fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 749fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::vector<const llvm::Type*> ArgTypes; 750fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::vector<llvm::Value*> Args; 751f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 752f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // Keep track of inout constraints. 753f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::string InOutConstraints; 754f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::vector<llvm::Value*> InOutArgs; 755f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::vector<const llvm::Type*> InOutArgTypes; 756fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 757fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) { 758fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string OutputConstraint(S.getOutputConstraint(i)->getStrData(), 759fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.getOutputConstraint(i)->getByteLength()); 760fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 761fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson TargetInfo::ConstraintInfo Info; 762fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson bool result = Target.validateOutputConstraint(OutputConstraint.c_str(), 763fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Info); 764fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(result && "Failed to parse output constraint"); 765fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 766fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Simplify the output constraint. 767a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1, Target); 768fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 769fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson LValue Dest = EmitLValue(S.getOutputExpr(i)); 770fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const llvm::Type *DestValueType = 771fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson cast<llvm::PointerType>(Dest.getAddress()->getType())->getElementType(); 772fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 773fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // If the first output operand is not a memory dest, we'll 774fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // make it the return value. 775fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (i == 0 && !(Info & TargetInfo::CI_AllowsMemory) && 776d79a726dc3c8af61b486948c97a183c7fe5b0179Dan Gohman DestValueType->isSingleValueType()) { 777fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ResultAddr = Dest.getAddress(); 778fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ResultType = DestValueType; 779fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += "=" + OutputConstraint; 780fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 781fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ArgTypes.push_back(Dest.getAddress()->getType()); 782cad3ab611ebd3bee3ce6395d649640047f904cdeAnders Carlsson Args.push_back(Dest.getAddress()); 783fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (i != 0) 784fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 785f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Constraints += "=*"; 786fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += OutputConstraint; 787f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 788f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 789f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson if (Info & TargetInfo::CI_ReadWrite) { 790f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // FIXME: This code should be shared with the code that handles inputs. 791f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutConstraints += ','; 792f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 793f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson const Expr *InputExpr = S.getOutputExpr(i); 794f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson llvm::Value *Arg; 795f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson if ((Info & TargetInfo::CI_AllowsRegister) || 796f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson !(Info & TargetInfo::CI_AllowsMemory)) { 797d79a726dc3c8af61b486948c97a183c7fe5b0179Dan Gohman if (ConvertType(InputExpr->getType())->isSingleValueType()) { 798f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Arg = EmitScalarExpr(InputExpr); 799f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } else { 800662174c82ef46b19a2329c7d37208e1d12dfb7b3Daniel Dunbar ErrorUnsupported(&S, "asm statement passing multiple-value types as inputs"); 801f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 802f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } else { 803f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson LValue Dest = EmitLValue(InputExpr); 804f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Arg = Dest.getAddress(); 805f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutConstraints += '*'; 806f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 807f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 808f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutArgTypes.push_back(Arg->getType()); 809f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutArgs.push_back(Arg); 810f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutConstraints += OutputConstraint; 811f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 812fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 813fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 814fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson unsigned NumConstraints = S.getNumOutputs() + S.getNumInputs(); 815fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 816fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) { 817fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const Expr *InputExpr = S.getInputExpr(i); 818fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 819fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string InputConstraint(S.getInputConstraint(i)->getStrData(), 820fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.getInputConstraint(i)->getByteLength()); 821fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 822fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson TargetInfo::ConstraintInfo Info; 823fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson bool result = Target.validateInputConstraint(InputConstraint.c_str(), 824fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson NumConstraints, 825fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Info); 826fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(result && "Failed to parse input constraint"); 827fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 828fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (i != 0 || S.getNumOutputs() > 0) 829fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 830fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 831fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Simplify the input constraint. 832a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio InputConstraint = SimplifyConstraint(InputConstraint.c_str(), Target); 833fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 834fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::Value *Arg; 835fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 836fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if ((Info & TargetInfo::CI_AllowsRegister) || 837fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson !(Info & TargetInfo::CI_AllowsMemory)) { 838d79a726dc3c8af61b486948c97a183c7fe5b0179Dan Gohman if (ConvertType(InputExpr->getType())->isSingleValueType()) { 839fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Arg = EmitScalarExpr(InputExpr); 840fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 841662174c82ef46b19a2329c7d37208e1d12dfb7b3Daniel Dunbar ErrorUnsupported(&S, "asm statement passing multiple-value types as inputs"); 842fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 843fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 844fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson LValue Dest = EmitLValue(InputExpr); 845fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Arg = Dest.getAddress(); 846fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += '*'; 847fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 848fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 849fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ArgTypes.push_back(Arg->getType()); 850fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Args.push_back(Arg); 851fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += InputConstraint; 852fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 853fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 854f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // Append the "input" part of inout constraints last. 855f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { 856f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson ArgTypes.push_back(InOutArgTypes[i]); 857f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Args.push_back(InOutArgs[i]); 858f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 859f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Constraints += InOutConstraints; 860f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 861fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Clobbers 862fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) { 863fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Clobber(S.getClobber(i)->getStrData(), 864fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.getClobber(i)->getByteLength()); 865fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 866fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Clobber = Target.getNormalizedGCCRegisterName(Clobber.c_str()); 867fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 868ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson if (i != 0 || NumConstraints != 0) 869fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 870ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson 871ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson Constraints += "~{"; 872fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += Clobber; 873ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson Constraints += '}'; 874fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 875fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 876fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Add machine specific clobbers 877fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (const char *C = Target.getClobbers()) { 878fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (!Constraints.empty()) 879fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 880fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += C; 881fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 882f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 883fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const llvm::FunctionType *FTy = 884fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::FunctionType::get(ResultType, ArgTypes, false); 885fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 886fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::InlineAsm *IA = 887fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::InlineAsm::get(FTy, AsmString, Constraints, 888fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.isVolatile() || S.getNumOutputs() == 0); 889fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::Value *Result = Builder.CreateCall(IA, Args.begin(), Args.end(), ""); 8901e692ace08959399794363e77499b73da5494af9Eli Friedman if (ResultAddr) // FIXME: volatility 891fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Builder.CreateStore(Result, ResultAddr); 892fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 893