CGStmt.cpp revision ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298
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" 187d22bf00dbabca86ba791f56a99e006181fa22ddChris Lattner#include "clang/Basic/PrettyStackTrace.h" 19fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson#include "clang/Basic/TargetInfo.h" 20fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson#include "llvm/ADT/StringExtras.h" 2117d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson#include "llvm/InlineAsm.h" 2217d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson#include "llvm/Intrinsics.h" 23ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson#include "llvm/Target/TargetData.h" 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace CodeGen; 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Statement Emission 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 310912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarvoid CodeGenFunction::EmitStopPoint(const Stmt *S) { 32e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson if (CGDebugInfo *DI = getDebugInfo()) { 3360e4fd95ed8c1f99697f4d9f73d07717b6e21048Devang Patel if (isa<DeclStmt>(S)) 3460e4fd95ed8c1f99697f4d9f73d07717b6e21048Devang Patel DI->setLocation(S->getLocEnd()); 3560e4fd95ed8c1f99697f4d9f73d07717b6e21048Devang Patel else 3660e4fd95ed8c1f99697f4d9f73d07717b6e21048Devang Patel DI->setLocation(S->getLocStart()); 375a6fbcfd8c15a2296f94a0473a68ec09d429827fDevang Patel DI->UpdateLineDirectiveRegion(Builder); 384d939e64142126b872e39c11dc995aa993f137feDevang Patel DI->EmitStopPoint(Builder); 390912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar } 400912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar} 410912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitStmt(const Stmt *S) { 435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(S && "Null statement?"); 44a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar 450912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // Check if we can handle this without bothering to generate an 460912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // insert point or debug info. 470912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (EmitSimpleStmt(S)) 480912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar return; 490912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 50d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar // Check if we are generating unreachable code. 51d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar if (!HaveInsertPoint()) { 52d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar // If so, and the statement doesn't contain a label, then we do not need to 53d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar // generate actual code. This is safe because (1) the current point is 54d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar // unreachable, so we don't need to execute the code, and (2) we've already 55d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar // handled the statements which update internal data structures (like the 56d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar // local variable map) which could be used by subsequent statements. 57d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar if (!ContainsLabel(S)) { 58d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar // Verify that any decl statements were handled as simple, they may be in 59d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar // scope of subsequent reachable statements. 60d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar assert(!isa<DeclStmt>(*S) && "Unexpected DeclStmt!"); 61d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar return; 62d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar } 63d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar 64d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar // Otherwise, make a new block to hold the code. 65d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar EnsureInsertPoint(); 66d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar } 67d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar 680912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // Generate a stoppoint if we are emitting debug info. 690912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(S); 70e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta 715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (S->getStmtClass()) { 722a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::NoStmtClass: 732a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::CXXCatchStmtClass: 742a41637a995affa1563f4d82a8b026e326a2faa0John McCall llvm_unreachable("invalid statement class to emit generically"); 752a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::NullStmtClass: 762a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::CompoundStmtClass: 772a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::DeclStmtClass: 782a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::LabelStmtClass: 792a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::GotoStmtClass: 802a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::BreakStmtClass: 812a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::ContinueStmtClass: 822a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::DefaultStmtClass: 832a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::CaseStmtClass: 842a41637a995affa1563f4d82a8b026e326a2faa0John McCall llvm_unreachable("should have emitted these statements as simple"); 85cd5e60e1d4093b9a757cc85e35fccc093f8f8527Daniel Dunbar 862a41637a995affa1563f4d82a8b026e326a2faa0John McCall#define STMT(Type, Base) 872a41637a995affa1563f4d82a8b026e326a2faa0John McCall#define ABSTRACT_STMT(Op) 882a41637a995affa1563f4d82a8b026e326a2faa0John McCall#define EXPR(Type, Base) \ 892a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::Type##Class: 902a41637a995affa1563f4d82a8b026e326a2faa0John McCall#include "clang/AST/StmtNodes.inc" 91cd5b22e12b6513163dd131589746c194090f14e6John McCall { 92cd5b22e12b6513163dd131589746c194090f14e6John McCall // Remember the block we came in on. 93cd5b22e12b6513163dd131589746c194090f14e6John McCall llvm::BasicBlock *incoming = Builder.GetInsertBlock(); 94cd5b22e12b6513163dd131589746c194090f14e6John McCall assert(incoming && "expression emission must have an insertion point"); 95cd5b22e12b6513163dd131589746c194090f14e6John McCall 962a41637a995affa1563f4d82a8b026e326a2faa0John McCall EmitIgnoredExpr(cast<Expr>(S)); 971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 98cd5b22e12b6513163dd131589746c194090f14e6John McCall llvm::BasicBlock *outgoing = Builder.GetInsertBlock(); 99cd5b22e12b6513163dd131589746c194090f14e6John McCall assert(outgoing && "expression emission cleared block!"); 100cd5b22e12b6513163dd131589746c194090f14e6John McCall 101cd5b22e12b6513163dd131589746c194090f14e6John McCall // The expression emitters assume (reasonably!) that the insertion 102cd5b22e12b6513163dd131589746c194090f14e6John McCall // point is always set. To maintain that, the call-emission code 103cd5b22e12b6513163dd131589746c194090f14e6John McCall // for noreturn functions has to enter a new block with no 104cd5b22e12b6513163dd131589746c194090f14e6John McCall // predecessors. We want to kill that block and mark the current 105cd5b22e12b6513163dd131589746c194090f14e6John McCall // insertion point unreachable in the common case of a call like 106cd5b22e12b6513163dd131589746c194090f14e6John McCall // "exit();". Since expression emission doesn't otherwise create 107cd5b22e12b6513163dd131589746c194090f14e6John McCall // blocks with no predecessors, we can just test for that. 108cd5b22e12b6513163dd131589746c194090f14e6John McCall // However, we must be careful not to do this to our incoming 109cd5b22e12b6513163dd131589746c194090f14e6John McCall // block, because *statement* emission does sometimes create 110cd5b22e12b6513163dd131589746c194090f14e6John McCall // reachable blocks which will have no predecessors until later in 111cd5b22e12b6513163dd131589746c194090f14e6John McCall // the function. This occurs with, e.g., labels that are not 112cd5b22e12b6513163dd131589746c194090f14e6John McCall // reachable by fallthrough. 113cd5b22e12b6513163dd131589746c194090f14e6John McCall if (incoming != outgoing && outgoing->use_empty()) { 114cd5b22e12b6513163dd131589746c194090f14e6John McCall outgoing->eraseFromParent(); 115cd5b22e12b6513163dd131589746c194090f14e6John McCall Builder.ClearInsertionPoint(); 1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 118cd5b22e12b6513163dd131589746c194090f14e6John McCall } 1192a41637a995affa1563f4d82a8b026e326a2faa0John McCall 1201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Stmt::IndirectGotoStmtClass: 1210ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar EmitIndirectGotoStmt(cast<IndirectGotoStmt>(*S)); break; 1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break; 1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break; 1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::DoStmtClass: EmitDoStmt(cast<DoStmt>(*S)); break; 1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::ForStmtClass: EmitForStmt(cast<ForStmt>(*S)); break; 1271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break; 129a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar 13051b09f2c528c8460b5465c676173324e44176d62Devang Patel case Stmt::SwitchStmtClass: EmitSwitchStmt(cast<SwitchStmt>(*S)); break; 131fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case Stmt::AsmStmtClass: EmitAsmStmt(cast<AsmStmt>(*S)); break; 1320a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar 1330a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtTryStmtClass: 13464d5d6c5903157c521af496479d06dc26032d718Anders Carlsson EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S)); 1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 1360a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtCatchStmtClass: 137dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson assert(0 && "@catch statements should be handled by EmitObjCAtTryStmt"); 138dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson break; 1390a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtFinallyStmtClass: 14064d5d6c5903157c521af496479d06dc26032d718Anders Carlsson assert(0 && "@finally statements should be handled by EmitObjCAtTryStmt"); 1410a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 1420a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtThrowStmtClass: 14364d5d6c5903157c521af496479d06dc26032d718Anders Carlsson EmitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(*S)); 1440a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 1450a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtSynchronizedStmtClass: 14610cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattner EmitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(*S)); 1470a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 1481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Stmt::ObjCForCollectionStmtClass: 1493d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson EmitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(*S)); 1500a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 1516815e941998659a55c20c147861b0f437928c3d8Anders Carlsson 1526815e941998659a55c20c147861b0f437928c3d8Anders Carlsson case Stmt::CXXTryStmtClass: 1536815e941998659a55c20c147861b0f437928c3d8Anders Carlsson EmitCXXTryStmt(cast<CXXTryStmt>(*S)); 1546815e941998659a55c20c147861b0f437928c3d8Anders Carlsson break; 1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1580912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarbool CodeGenFunction::EmitSimpleStmt(const Stmt *S) { 1590912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar switch (S->getStmtClass()) { 1600912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar default: return false; 1610912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::NullStmtClass: break; 1620912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break; 163d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break; 1640912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break; 1650912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break; 1660912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::BreakStmtClass: EmitBreakStmt(cast<BreakStmt>(*S)); break; 1670912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::ContinueStmtClass: EmitContinueStmt(cast<ContinueStmt>(*S)); break; 1680912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::DefaultStmtClass: EmitDefaultStmt(cast<DefaultStmt>(*S)); break; 1690912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::CaseStmtClass: EmitCaseStmt(cast<CaseStmt>(*S)); break; 1700912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar } 1710912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 1720912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar return true; 1730912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar} 1740912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 1753379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true, 1763379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// this captures the expression result of the last sub-statement and returns it 1773379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// (for use by the statement expression extension). 1789b65551d0b387a7597fb39356a4d8ef10046445eChris LattnerRValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, 179558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall AggValueSlot AggSlot) { 1807d22bf00dbabca86ba791f56a99e006181fa22ddChris Lattner PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),S.getLBracLoc(), 1817d22bf00dbabca86ba791f56a99e006181fa22ddChris Lattner "LLVM IR generation of compound statement ('{}')"); 1821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 183e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson CGDebugInfo *DI = getDebugInfo(); 1841c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta if (DI) { 185bbd9fa4b4a0fea47f94ac3eb4eaf5cc8079defe1Devang Patel DI->setLocation(S.getLBracLoc()); 1864d939e64142126b872e39c11dc995aa993f137feDevang Patel DI->EmitRegionStart(Builder); 1871c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta } 1881c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta 189c71c845fe77ee1f891d60232ec320912d88557eeAnders Carlsson // Keep track of the current cleanup stack depth. 190f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope Scope(*this); 1911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1923379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner for (CompoundStmt::const_body_iterator I = S.body_begin(), 1933379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner E = S.body_end()-GetLast; I != E; ++I) 1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(*I); 195e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta 1961c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta if (DI) { 197cd9199eb3dd1a665ea642f3918020a53e5ecb673Devang Patel DI->setLocation(S.getRBracLoc()); 1984d939e64142126b872e39c11dc995aa993f137feDevang Patel DI->EmitRegionEnd(Builder); 1991c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta } 2001c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta 20117d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson RValue RV; 2021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (!GetLast) 20317d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson RV = RValue::get(0); 20417d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson else { 2051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // We have to special case labels here. They are statements, but when put 20617d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson // at the end of a statement expression, they yield the value of their 20717d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson // subexpression. Handle this by walking through all labels we encounter, 20817d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson // emitting them before we evaluate the subexpr. 20917d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson const Stmt *LastStmt = S.body_back(); 21017d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson while (const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) { 211ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner EmitLabel(LS->getDecl()); 21217d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson LastStmt = LS->getSubStmt(); 21317d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson } 2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21517d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson EnsureInsertPoint(); 2161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 217558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall RV = EmitAnyExpr(cast<Expr>(LastStmt), AggSlot); 21891d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner } 219a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar 22017d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson return RV; 2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 223aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbarvoid CodeGenFunction::SimplifyForwardingBlocks(llvm::BasicBlock *BB) { 224aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar llvm::BranchInst *BI = dyn_cast<llvm::BranchInst>(BB->getTerminator()); 2251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 226aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar // If there is a cleanup stack, then we it isn't worth trying to 227aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar // simplify this block (we would need to remove it from the scope map 228aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar // and cleanup entry). 229f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!EHStack.empty()) 230aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar return; 231aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar 232aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar // Can only simplify direct branches. 233aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar if (!BI || !BI->isUnconditional()) 234aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar return; 235aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar 236aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar BB->replaceAllUsesWith(BI->getSuccessor(0)); 237aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar BI->eraseFromParent(); 238aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar BB->eraseFromParent(); 239aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar} 240aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar 241a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbarvoid CodeGenFunction::EmitBlock(llvm::BasicBlock *BB, bool IsFinished) { 242548ce5e78215a34f409d597bb2c1e9f897a8eda3John McCall llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); 243548ce5e78215a34f409d597bb2c1e9f897a8eda3John McCall 244d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // Fall out of the current block (if necessary). 245d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(BB); 246a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar 247a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar if (IsFinished && BB->use_empty()) { 248a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar delete BB; 249a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar return; 250a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar } 251a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar 252839cbaa004a24e8f1ea14db5ed76e3d25ed28996John McCall // Place the block after the current block, if possible, or else at 253839cbaa004a24e8f1ea14db5ed76e3d25ed28996John McCall // the end of the function. 254548ce5e78215a34f409d597bb2c1e9f897a8eda3John McCall if (CurBB && CurBB->getParent()) 255548ce5e78215a34f409d597bb2c1e9f897a8eda3John McCall CurFn->getBasicBlockList().insertAfter(CurBB, BB); 256839cbaa004a24e8f1ea14db5ed76e3d25ed28996John McCall else 257839cbaa004a24e8f1ea14db5ed76e3d25ed28996John McCall CurFn->getBasicBlockList().push_back(BB); 258d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar Builder.SetInsertPoint(BB); 259d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar} 260d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar 261d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbarvoid CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) { 262d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // Emit a branch from the current block to the target one if this 263d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // was a real block. If this was just a fall-through block after a 264d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // terminator, don't emit it. 265d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); 266d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar 267d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar if (!CurBB || CurBB->getTerminator()) { 268d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // If there is no insert point or the previous block is already 269d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // terminated, don't touch it. 2705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 2715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, create a fall-through branch. 272d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar Builder.CreateBr(Target); 2735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2745e08ad3cc62ab94649959ae227a9a411a729bf49Daniel Dunbar 2755e08ad3cc62ab94649959ae227a9a411a729bf49Daniel Dunbar Builder.ClearInsertionPoint(); 2765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 278f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallCodeGenFunction::JumpDest 279ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris LattnerCodeGenFunction::getJumpDestForLabel(const LabelDecl *D) { 280ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner JumpDest &Dest = LabelMap[D]; 281ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall if (Dest.isValid()) return Dest; 282f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 283f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Create, but don't insert, the new block. 284ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner Dest = JumpDest(createBasicBlock(D->getName()), 285ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EHScopeStack::stable_iterator::invalid(), 286ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall NextCleanupDestIndex++); 287f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return Dest; 288f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 289f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 290ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattnervoid CodeGenFunction::EmitLabel(const LabelDecl *D) { 291ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner JumpDest &Dest = LabelMap[D]; 292f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 293ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall // If we didn't need a forward reference to this label, just go 294f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // ahead and create a destination at the current scope. 295ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall if (!Dest.isValid()) { 296ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner Dest = getJumpDestInCurrentScope(D->getName()); 297f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 298f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Otherwise, we need to give this label a target depth and remove 299f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // it from the branch-fixups list. 300f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else { 301ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall assert(!Dest.getScopeDepth().isValid() && "already emitted label!"); 302ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall Dest = JumpDest(Dest.getBlock(), 303ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EHStack.stable_begin(), 304ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall Dest.getDestIndex()); 305f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 306ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall ResolveBranchFixups(Dest.getBlock()); 307f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 308f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 309ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(Dest.getBlock()); 31091d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner} 31191d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner 31291d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner 31391d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattnervoid CodeGenFunction::EmitLabelStmt(const LabelStmt &S) { 314ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner EmitLabel(S.getDecl()); 3155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getSubStmt()); 3165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitGotoStmt(const GotoStmt &S) { 3190912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // If this code is reachable then emit a stop point (if generating 3200912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // debug info). We have to do this ourselves because we are on the 3210912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // "simple" statement path. 3220912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (HaveInsertPoint()) 3230912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(&S); 32436a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump 325f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBranchThroughCleanup(getJumpDestForLabel(S.getLabel())); 3265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3283d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner 3290ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbarvoid CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) { 330ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner if (const LabelDecl *Target = S.getConstantTarget()) { 33195c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall EmitBranchThroughCleanup(getJumpDestForLabel(Target)); 33295c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall return; 33395c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall } 33495c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall 33549c952f853fe2d15dd9c9ff2a29c696bd18fca13Chris Lattner // Ensure that we have an i8* for our PHI node. 336d9becd1846e2c72bf6ad283faa1b048f33dd3afeChris Lattner llvm::Value *V = Builder.CreateBitCast(EmitScalarExpr(S.getTarget()), 337d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Int8PtrTy, "addr"); 3383d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); 3393d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner 3403d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner 3413d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner // Get the basic block for the indirect goto. 3423d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner llvm::BasicBlock *IndGotoBB = GetIndirectGotoBlock(); 3433d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner 3443d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner // The first instruction in the block has to be the PHI for the switch dest, 3453d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner // add an entry for this branch. 3463d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner cast<llvm::PHINode>(IndGotoBB->begin())->addIncoming(V, CurBB); 3473d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner 3483d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner EmitBranch(IndGotoBB); 3490ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar} 3500ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar 35162b72f642207ba2ba433d686df924dc9594e9897Chris Lattnervoid CodeGenFunction::EmitIfStmt(const IfStmt &S) { 3525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.4.1: The first substatement is executed if the expression compares 3535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // unequal to 0. The condition must be a scalar type. 354f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ConditionScope(*this); 35501234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor 3568cfe5a784133d90bf329fd20801824a6f71bb8caDouglas Gregor if (S.getConditionVariable()) 357b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall EmitAutoVarDecl(*S.getConditionVariable()); 3581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3599bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // If the condition constant folds and can be elided, try to avoid emitting 3609bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // the condition and the dead arm of the if/else. 36131a0984b5cb4af99d2407c0f25bf5af68df681c6Chris Lattner if (int Cond = ConstantFoldsToSimpleInteger(S.getCond())) { 36262b72f642207ba2ba433d686df924dc9594e9897Chris Lattner // Figure out which block (then or else) is executed. 36362b72f642207ba2ba433d686df924dc9594e9897Chris Lattner const Stmt *Executed = S.getThen(), *Skipped = S.getElse(); 3649bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner if (Cond == -1) // Condition false? 36562b72f642207ba2ba433d686df924dc9594e9897Chris Lattner std::swap(Executed, Skipped); 3661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 36762b72f642207ba2ba433d686df924dc9594e9897Chris Lattner // If the skipped block has no labels in it, just emit the executed block. 36862b72f642207ba2ba433d686df924dc9594e9897Chris Lattner // This avoids emitting dead code and simplifies the CFG substantially. 3699bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner if (!ContainsLabel(Skipped)) { 37001234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor if (Executed) { 371f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ExecutedScope(*this); 37262b72f642207ba2ba433d686df924dc9594e9897Chris Lattner EmitStmt(Executed); 37301234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor } 37462b72f642207ba2ba433d686df924dc9594e9897Chris Lattner return; 37562b72f642207ba2ba433d686df924dc9594e9897Chris Lattner } 37662b72f642207ba2ba433d686df924dc9594e9897Chris Lattner } 3779bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner 3789bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // Otherwise, the condition did not fold, or we couldn't elide it. Just emit 3799bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // the conditional branch. 380781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar llvm::BasicBlock *ThenBlock = createBasicBlock("if.then"); 381781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar llvm::BasicBlock *ContBlock = createBasicBlock("if.end"); 382781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar llvm::BasicBlock *ElseBlock = ContBlock; 3835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getElse()) 384781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar ElseBlock = createBasicBlock("if.else"); 385781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar EmitBranchOnBoolExpr(S.getCond(), ThenBlock, ElseBlock); 3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the 'then' code. 38801234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor EmitBlock(ThenBlock); 38901234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor { 390f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ThenScope(*this); 39101234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor EmitStmt(S.getThen()); 39201234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor } 393d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(ContBlock); 3941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the 'else' code if present. 3965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (const Stmt *Else = S.getElse()) { 3975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ElseBlock); 39801234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor { 399f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ElseScope(*this); 40001234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor EmitStmt(Else); 40101234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor } 402d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(ContBlock); 4035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the continuation block for code after the if. 406c22d665ede76f70228055d638a087f4bd438292dDaniel Dunbar EmitBlock(ContBlock, true); 4075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitWhileStmt(const WhileStmt &S) { 410f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit the header for the loop, which will also become 411f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // the continue target. 412f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond"); 413ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(LoopHeader.getBlock()); 414f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 415f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Create an exit block for when the condition fails, which will 416f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // also become the break target. 417f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest LoopExit = getJumpDestInCurrentScope("while.end"); 41872cac2ccce8058833f56358e3391e28a8ddeeaa4Mike Stump 41972cac2ccce8058833f56358e3391e28a8ddeeaa4Mike Stump // Store the blocks to use for break and continue. 420f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall BreakContinueStack.push_back(BreakContinue(LoopExit, LoopHeader)); 4211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4225656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor // C++ [stmt.while]p2: 4235656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor // When the condition of a while statement is a declaration, the 4245656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor // scope of the variable that is declared extends from its point 4255656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor // of declaration (3.3.2) to the end of the while statement. 4265656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor // [...] 4275656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor // The object created in a condition is destroyed and created 4285656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor // with each iteration of the loop. 429f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ConditionScope(*this); 4305656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor 431f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (S.getConditionVariable()) 432b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall EmitAutoVarDecl(*S.getConditionVariable()); 4335656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor 43416b16206741f5139c4ad870632db8f9ea4c6c943Mike Stump // Evaluate the conditional in the while header. C99 6.8.5.1: The 43516b16206741f5139c4ad870632db8f9ea4c6c943Mike Stump // evaluation of the controlling expression takes place before each 43616b16206741f5139c4ad870632db8f9ea4c6c943Mike Stump // execution of the loop body. 4375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 4385656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor 4392c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel // while(1) is common, avoid extra exit blocks. Be sure 4405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // to correctly handle break/continue though. 4412c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel bool EmitBoolCondBranch = true; 4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) 4432c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (C->isOne()) 4442c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel EmitBoolCondBranch = false; 4451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // As long as the condition is true, go to the loop body. 447f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *LoopBody = createBasicBlock("while.body"); 448f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (EmitBoolCondBranch) { 449ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); 450f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (ConditionScope.requiresCleanups()) 451f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ExitBlock = createBasicBlock("while.exit"); 452f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 453f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock); 454f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 455ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall if (ExitBlock != LoopExit.getBlock()) { 456f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBlock(ExitBlock); 457f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBranchThroughCleanup(LoopExit); 458f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 459f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 4605656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor 461f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit the loop body. We have to emit this in a cleanup scope 462f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // because it might be a singleton DeclStmt. 4635656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor { 464f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope BodyScope(*this); 4655656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor EmitBlock(LoopBody); 4665656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor EmitStmt(S.getBody()); 4675656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor } 468da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 4691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump BreakContinueStack.pop_back(); 4701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 471f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Immediately force cleanup. 472f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ConditionScope.ForceCleanup(); 4735656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor 474f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Branch to the loop header again. 475ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBranch(LoopHeader.getBlock()); 4761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the exit block. 478ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(LoopExit.getBlock(), true); 4795656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor 480aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar // The LoopHeader typically is just a branch if we skipped emitting 481aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar // a branch, try to erase it. 482f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!EmitBoolCondBranch) 483ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall SimplifyForwardingBlocks(LoopHeader.getBlock()); 4845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitDoStmt(const DoStmt &S) { 487f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest LoopExit = getJumpDestInCurrentScope("do.end"); 488f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest LoopCond = getJumpDestInCurrentScope("do.cond"); 4891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 490da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 491f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall BreakContinueStack.push_back(BreakContinue(LoopExit, LoopCond)); 4921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 493f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit the body of the loop. 494f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *LoopBody = createBasicBlock("do.body"); 495f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBlock(LoopBody); 496f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall { 497f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope BodyScope(*this); 498f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitStmt(S.getBody()); 499f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 5001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 501e4b6d342c29d5cb9d311756100df1603810fa892Anders Carlsson BreakContinueStack.pop_back(); 5021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 503ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(LoopCond.getBlock()); 5041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5.2: "The evaluation of the controlling expression takes place 5065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // after each execution of the loop body." 5071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the conditional in the while header. 5095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5p2/p4: The first substatement is executed if the expression 5105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // compares unequal to 0. The condition must be a scalar type. 5115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 51205f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 51305f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // "do {} while (0)" is common in macros, avoid extra blocks. Be sure 51405f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // to correctly handle break/continue though. 51505f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel bool EmitBoolCondBranch = true; 5161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) 51705f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (C->isZero()) 51805f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel EmitBoolCondBranch = false; 51905f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 5205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // As long as the condition is true, iterate the loop. 52105f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (EmitBoolCondBranch) 522ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall Builder.CreateCondBr(BoolCondVal, LoopBody, LoopExit.getBlock()); 5231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the exit block. 525ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(LoopExit.getBlock()); 52605f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 527aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar // The DoCond block typically is just a branch if we skipped 528aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar // emitting a branch, try to erase it. 529aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar if (!EmitBoolCondBranch) 530ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall SimplifyForwardingBlocks(LoopCond.getBlock()); 5315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 5325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitForStmt(const ForStmt &S) { 534f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest LoopExit = getJumpDestInCurrentScope("for.end"); 535f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 536f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ForScope(*this); 537da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 5380554e0e30d24d9ad7d5e12f8e7583ebb5c9715bfDevang Patel CGDebugInfo *DI = getDebugInfo(); 5390554e0e30d24d9ad7d5e12f8e7583ebb5c9715bfDevang Patel if (DI) { 5400554e0e30d24d9ad7d5e12f8e7583ebb5c9715bfDevang Patel DI->setLocation(S.getSourceRange().getBegin()); 5410554e0e30d24d9ad7d5e12f8e7583ebb5c9715bfDevang Patel DI->EmitRegionStart(Builder); 5420554e0e30d24d9ad7d5e12f8e7583ebb5c9715bfDevang Patel } 5430554e0e30d24d9ad7d5e12f8e7583ebb5c9715bfDevang Patel 5445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the first part before the loop. 5455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getInit()) 5465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getInit()); 5475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Start the loop with a block that tests the condition. 549f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If there's an increment, the continue scope will be overwritten 550f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // later. 551f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest Continue = getJumpDestInCurrentScope("for.cond"); 552ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall llvm::BasicBlock *CondBlock = Continue.getBlock(); 5535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(CondBlock); 5545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 555d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor // Create a cleanup scope for the condition variable cleanups. 556f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ConditionScope(*this); 55799e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor 558d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor llvm::Value *BoolCondVal = 0; 5595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getCond()) { 56099e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor // If the for statement has a condition scope, emit the local variable 56199e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor // declaration. 562ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); 563d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor if (S.getConditionVariable()) { 564b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall EmitAutoVarDecl(*S.getConditionVariable()); 565d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor } 566f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 567f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If there are any cleanups between here and the loop-exit scope, 568f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // create a block to stage a loop exit along. 569f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (ForScope.requiresCleanups()) 570f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ExitBlock = createBasicBlock("for.cond.cleanup"); 57199e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor 57231a0984b5cb4af99d2407c0f25bf5af68df681c6Chris Lattner // As long as the condition is true, iterate the loop. 5739615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 5741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5p2/p4: The first substatement is executed if the expression 5765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // compares unequal to 0. The condition must be a scalar type. 577d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor BoolCondVal = EvaluateExprAsBool(S.getCond()); 578f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock); 579f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 580ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall if (ExitBlock != LoopExit.getBlock()) { 581f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBlock(ExitBlock); 582f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBranchThroughCleanup(LoopExit); 583f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 5841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump EmitBlock(ForBody); 5865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 5875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Treat it as a non-zero constant. Don't even create a new block for the 5885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // body, just fall into it. 5895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 5905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // If the for loop doesn't have an increment we can just use the 592f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // condition as the continue block. Otherwise we'll need to create 593f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // a block for it (in the current scope, i.e. in the scope of the 594f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // condition), and that we will become our continue block. 595da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner if (S.getInc()) 596f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Continue = getJumpDestInCurrentScope("for.inc"); 5971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 598da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 599f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); 6003e9da66ac7e88d64d30ee777588677320660cf84Mike Stump 601d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor { 602d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor // Create a separate cleanup scope for the body, in case it is not 603d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor // a compound statement. 604f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope BodyScope(*this); 605d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor EmitStmt(S.getBody()); 606d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor } 607da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 6085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If there is an increment, emit it next. 609ad12b6d643aba6c36f5cec4c9beb4977a12eace4Daniel Dunbar if (S.getInc()) { 610ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(Continue.getBlock()); 611883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner EmitStmt(S.getInc()); 612ad12b6d643aba6c36f5cec4c9beb4977a12eace4Daniel Dunbar } 6131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 61445d3fe1898d3726d269a0bd2ccb8527102e29d79Douglas Gregor BreakContinueStack.pop_back(); 615f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 616f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ConditionScope.ForceCleanup(); 617f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBranch(CondBlock); 618f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 619f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ForScope.ForceCleanup(); 620f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 621bbd9fa4b4a0fea47f94ac3eb4eaf5cc8079defe1Devang Patel if (DI) { 622bbd9fa4b4a0fea47f94ac3eb4eaf5cc8079defe1Devang Patel DI->setLocation(S.getSourceRange().getEnd()); 6234d939e64142126b872e39c11dc995aa993f137feDevang Patel DI->EmitRegionEnd(Builder); 624bbd9fa4b4a0fea47f94ac3eb4eaf5cc8079defe1Devang Patel } 6255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 626da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Emit the fall-through block. 627ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(LoopExit.getBlock(), true); 6285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 6295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 63029e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbarvoid CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) { 63129e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar if (RV.isScalar()) { 63229e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar Builder.CreateStore(RV.getScalarVal(), ReturnValue); 63329e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } else if (RV.isAggregate()) { 63429e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar EmitAggregateCopy(ReturnValue, RV.getAggregateAddr(), Ty); 63529e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } else { 63629e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false); 63729e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } 63882d8ef0be44ddba608c1ce5c8b6b48da83bc1821Anders Carlsson EmitBranchThroughCleanup(ReturnBlock); 63929e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar} 64029e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar 6415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand 6425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// if the function returns void, or may be missing one if the function returns 6435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// non-void. Fun stuff :). 6445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { 6455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the result value, even if unused, to evalute the side effects. 6465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const Expr *RV = S.getRetValue(); 6471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6485ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // FIXME: Clean this up by using an LValue for ReturnTemp, 6495ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // EmitStoreThroughLValue, and EmitAnyExpr. 650d86c477fb5d3fc34864afecbbb5443da9355e8fbDouglas Gregor if (S.getNRVOCandidate() && S.getNRVOCandidate()->isNRVOVariable() && 651d86c477fb5d3fc34864afecbbb5443da9355e8fbDouglas Gregor !Target.useGlobalsForAutomaticVariables()) { 652d86c477fb5d3fc34864afecbbb5443da9355e8fbDouglas Gregor // Apply the named return value optimization for this return statement, 653d86c477fb5d3fc34864afecbbb5443da9355e8fbDouglas Gregor // which means doing nothing: the appropriate result has already been 654d86c477fb5d3fc34864afecbbb5443da9355e8fbDouglas Gregor // constructed into the NRVO variable. 6553d91bbcdab155181556969cad6ec97014405acedDouglas Gregor 6563d91bbcdab155181556969cad6ec97014405acedDouglas Gregor // If there is an NRVO flag for this variable, set it to 1 into indicate 6573d91bbcdab155181556969cad6ec97014405acedDouglas Gregor // that the cleanup code should not destroy the variable. 658d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall if (llvm::Value *NRVOFlag = NRVOFlags[S.getNRVOCandidate()]) 659d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Builder.CreateStore(Builder.getTrue(), NRVOFlag); 660d86c477fb5d3fc34864afecbbb5443da9355e8fbDouglas Gregor } else if (!ReturnValue) { 6615ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // Make sure not to return anything, but evaluate the expression 6625ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // for side effects. 6635ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar if (RV) 664144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman EmitAnyExpr(RV); 6655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else if (RV == 0) { 6665ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // Do nothing (return value is left uninitialized) 667d54b6ac2f4f6f0bd0076cbfa885b57277066f06cEli Friedman } else if (FnRetTy->isReferenceType()) { 668d54b6ac2f4f6f0bd0076cbfa885b57277066f06cEli Friedman // If this function returns a reference, take the address of the expression 669d54b6ac2f4f6f0bd0076cbfa885b57277066f06cEli Friedman // rather than the value. 67032f36baa6c8d491c374af622b4e3ac28d597453cAnders Carlsson RValue Result = EmitReferenceBindingToExpr(RV, /*InitializedDecl=*/0); 67133fd1fc1814a5573c972840d49317989e20deaceDouglas Gregor Builder.CreateStore(Result.getScalarVal(), ReturnValue); 6724b0029d5f8742760981a3bd58004f75454090a61Chris Lattner } else if (!hasAggregateLLVMType(RV->getType())) { 6735ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar Builder.CreateStore(EmitScalarExpr(RV), ReturnValue); 6749b2dc287177394a8f73833e2ad4f7ca8cd6f22bbChris Lattner } else if (RV->getType()->isAnyComplexType()) { 6755ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar EmitComplexExprIntoAddr(RV, ReturnValue, false); 6765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 677558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall EmitAggExpr(RV, AggValueSlot::forAddr(ReturnValue, false, true)); 6785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 679144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman 68082d8ef0be44ddba608c1ce5c8b6b48da83bc1821Anders Carlsson EmitBranchThroughCleanup(ReturnBlock); 6815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 6825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitDeclStmt(const DeclStmt &S) { 68425b6ebf0f8c07514250ec76c987f84b6810d4d17Daniel Dunbar // As long as debug info is modeled with instructions, we have to ensure we 68525b6ebf0f8c07514250ec76c987f84b6810d4d17Daniel Dunbar // have a place to insert here and write the stop point here. 68625b6ebf0f8c07514250ec76c987f84b6810d4d17Daniel Dunbar if (getDebugInfo()) { 68725b6ebf0f8c07514250ec76c987f84b6810d4d17Daniel Dunbar EnsureInsertPoint(); 68825b6ebf0f8c07514250ec76c987f84b6810d4d17Daniel Dunbar EmitStopPoint(&S); 68925b6ebf0f8c07514250ec76c987f84b6810d4d17Daniel Dunbar } 69025b6ebf0f8c07514250ec76c987f84b6810d4d17Daniel Dunbar 691e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek for (DeclStmt::const_decl_iterator I = S.decl_begin(), E = S.decl_end(); 692e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek I != E; ++I) 693e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek EmitDecl(**I); 6946fa5f0943a84233b2e1ec9716eae55643225bfd4Chris Lattner} 695da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 6960912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarvoid CodeGenFunction::EmitBreakStmt(const BreakStmt &S) { 697da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!"); 698da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 6990912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // If this code is reachable then emit a stop point (if generating 7000912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // debug info). We have to do this ourselves because we are on the 7010912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // "simple" statement path. 7020912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (HaveInsertPoint()) 7030912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(&S); 704ec9771d57f94cc204491b3174e88069d08cdd684Mike Stump 705f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest Block = BreakContinueStack.back().BreakBlock; 70682d8ef0be44ddba608c1ce5c8b6b48da83bc1821Anders Carlsson EmitBranchThroughCleanup(Block); 707da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner} 708da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 7090912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarvoid CodeGenFunction::EmitContinueStmt(const ContinueStmt &S) { 710da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 711da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 7120912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // If this code is reachable then emit a stop point (if generating 7130912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // debug info). We have to do this ourselves because we are on the 7140912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // "simple" statement path. 7150912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (HaveInsertPoint()) 7160912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(&S); 717ec9771d57f94cc204491b3174e88069d08cdd684Mike Stump 718f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest Block = BreakContinueStack.back().ContinueBlock; 71982d8ef0be44ddba608c1ce5c8b6b48da83bc1821Anders Carlsson EmitBranchThroughCleanup(Block); 720da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner} 72151b09f2c528c8460b5465c676173324e44176d62Devang Patel 722c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// EmitCaseStmtRange - If case statement range is not too big then 723c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// add multiple cases to switch instruction, one for each value within 724c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// the range. If range is too big then emit "if" condition check. 725c049e4f406a7f7179eba98659044a32508e53289Devang Patelvoid CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) { 7264efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar assert(S.getRHS() && "Expected RHS value in CaseStmt"); 727c049e4f406a7f7179eba98659044a32508e53289Devang Patel 72851fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson llvm::APSInt LHS = S.getLHS()->EvaluateAsInt(getContext()); 72951fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson llvm::APSInt RHS = S.getRHS()->EvaluateAsInt(getContext()); 7304efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar 73116f23570999cac1fa13597386938450843003840Daniel Dunbar // Emit the code for this case. We do this first to make sure it is 73216f23570999cac1fa13597386938450843003840Daniel Dunbar // properly chained from our predecessor before generating the 73316f23570999cac1fa13597386938450843003840Daniel Dunbar // switch machinery to enter this block. 734f84dcda7e2ab2f6d5be5a8c52d22ef4c442dd762Daniel Dunbar EmitBlock(createBasicBlock("sw.bb")); 73516f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *CaseDest = Builder.GetInsertBlock(); 73616f23570999cac1fa13597386938450843003840Daniel Dunbar EmitStmt(S.getSubStmt()); 73716f23570999cac1fa13597386938450843003840Daniel Dunbar 7384efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar // If range is empty, do nothing. 7394efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar if (LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS)) 7404efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar return; 741c049e4f406a7f7179eba98659044a32508e53289Devang Patel 742c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::APInt Range = RHS - LHS; 74316f23570999cac1fa13597386938450843003840Daniel Dunbar // FIXME: parameters such as this should not be hardcoded. 744c049e4f406a7f7179eba98659044a32508e53289Devang Patel if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) { 745c049e4f406a7f7179eba98659044a32508e53289Devang Patel // Range is small enough to add multiple switch instruction cases. 7464efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar for (unsigned i = 0, e = Range.getZExtValue() + 1; i != e; ++i) { 747d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall SwitchInsn->addCase(llvm::ConstantInt::get(getLLVMContext(), LHS), 748d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall CaseDest); 7492d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel LHS++; 7502d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel } 751c049e4f406a7f7179eba98659044a32508e53289Devang Patel return; 7521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 7531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 75416f23570999cac1fa13597386938450843003840Daniel Dunbar // The range is too big. Emit "if" condition into a new block, 75516f23570999cac1fa13597386938450843003840Daniel Dunbar // making sure to save and restore the current insertion point. 75616f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *RestoreBB = Builder.GetInsertBlock(); 75716f23570999cac1fa13597386938450843003840Daniel Dunbar 75816f23570999cac1fa13597386938450843003840Daniel Dunbar // Push this test onto the chain of range checks (which terminates 75916f23570999cac1fa13597386938450843003840Daniel Dunbar // in the default basic block). The switch's default will be changed 76016f23570999cac1fa13597386938450843003840Daniel Dunbar // to the top of this chain after switch emission is complete. 76116f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *FalseDest = CaseRangeBlock; 76255e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar CaseRangeBlock = createBasicBlock("sw.caserange"); 76316f23570999cac1fa13597386938450843003840Daniel Dunbar 76416f23570999cac1fa13597386938450843003840Daniel Dunbar CurFn->getBasicBlockList().push_back(CaseRangeBlock); 76516f23570999cac1fa13597386938450843003840Daniel Dunbar Builder.SetInsertPoint(CaseRangeBlock); 766c049e4f406a7f7179eba98659044a32508e53289Devang Patel 767c049e4f406a7f7179eba98659044a32508e53289Devang Patel // Emit range check. 7681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *Diff = 7691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Builder.CreateSub(SwitchInsn->getCondition(), 770d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::ConstantInt::get(getLLVMContext(), LHS), "tmp"); 7711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *Cond = 772d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Builder.CreateICmpULE(Diff, llvm::ConstantInt::get(getLLVMContext(), Range), 773d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall "inbounds"); 774c049e4f406a7f7179eba98659044a32508e53289Devang Patel Builder.CreateCondBr(Cond, CaseDest, FalseDest); 775c049e4f406a7f7179eba98659044a32508e53289Devang Patel 77616f23570999cac1fa13597386938450843003840Daniel Dunbar // Restore the appropriate insertion point. 777a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar if (RestoreBB) 778a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar Builder.SetInsertPoint(RestoreBB); 779a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar else 780a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar Builder.ClearInsertionPoint(); 781c049e4f406a7f7179eba98659044a32508e53289Devang Patel} 7822d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel 783c049e4f406a7f7179eba98659044a32508e53289Devang Patelvoid CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { 784c049e4f406a7f7179eba98659044a32508e53289Devang Patel if (S.getRHS()) { 785c049e4f406a7f7179eba98659044a32508e53289Devang Patel EmitCaseStmtRange(S); 786c049e4f406a7f7179eba98659044a32508e53289Devang Patel return; 787c049e4f406a7f7179eba98659044a32508e53289Devang Patel } 7881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 789f84dcda7e2ab2f6d5be5a8c52d22ef4c442dd762Daniel Dunbar EmitBlock(createBasicBlock("sw.bb")); 790c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::BasicBlock *CaseDest = Builder.GetInsertBlock(); 79151fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson llvm::APSInt CaseVal = S.getLHS()->EvaluateAsInt(getContext()); 792d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall SwitchInsn->addCase(llvm::ConstantInt::get(getLLVMContext(), CaseVal), 793d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall CaseDest); 7941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7955512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // Recursively emitting the statement is acceptable, but is not wonderful for 7965512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // code where we have many case statements nested together, i.e.: 7975512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // case 1: 7985512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // case 2: 7995512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // case 3: etc. 8005512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // Handling this recursively will create a new block for each case statement 8015512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // that falls through to the next case which is IR intensive. It also causes 8025512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // deep recursion which can run into stack depth limitations. Handle 8035512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // sequential non-range case statements specially. 8045512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner const CaseStmt *CurCase = &S; 8055512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner const CaseStmt *NextCase = dyn_cast<CaseStmt>(S.getSubStmt()); 8065512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner 8075512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // Otherwise, iteratively add consequtive cases to this switch stmt. 8085512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner while (NextCase && NextCase->getRHS() == 0) { 8095512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner CurCase = NextCase; 8105512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner CaseVal = CurCase->getLHS()->EvaluateAsInt(getContext()); 811d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall SwitchInsn->addCase(llvm::ConstantInt::get(getLLVMContext(), CaseVal), 812d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall CaseDest); 8135512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner 8145512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner NextCase = dyn_cast<CaseStmt>(CurCase->getSubStmt()); 8155512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner } 8161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8175512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // Normal default recursion for non-cases. 8185512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner EmitStmt(CurCase->getSubStmt()); 81951b09f2c528c8460b5465c676173324e44176d62Devang Patel} 82051b09f2c528c8460b5465c676173324e44176d62Devang Patel 82151b09f2c528c8460b5465c676173324e44176d62Devang Patelvoid CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) { 82216f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest(); 8231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump assert(DefaultBlock->empty() && 82455e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar "EmitDefaultStmt: Default block already defined?"); 82516f23570999cac1fa13597386938450843003840Daniel Dunbar EmitBlock(DefaultBlock); 82651b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getSubStmt()); 82751b09f2c528c8460b5465c676173324e44176d62Devang Patel} 82851b09f2c528c8460b5465c676173324e44176d62Devang Patel 82951b09f2c528c8460b5465c676173324e44176d62Devang Patelvoid CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { 830f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest SwitchExit = getJumpDestInCurrentScope("sw.epilog"); 831f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 832f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ConditionScope(*this); 833d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor 834d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor if (S.getConditionVariable()) 835b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall EmitAutoVarDecl(*S.getConditionVariable()); 836d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor 83751b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::Value *CondV = EmitScalarExpr(S.getCond()); 83851b09f2c528c8460b5465c676173324e44176d62Devang Patel 83951b09f2c528c8460b5465c676173324e44176d62Devang Patel // Handle nested switch statements. 84051b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::SwitchInst *SavedSwitchInsn = SwitchInsn; 841c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::BasicBlock *SavedCRBlock = CaseRangeBlock; 84251b09f2c528c8460b5465c676173324e44176d62Devang Patel 84316f23570999cac1fa13597386938450843003840Daniel Dunbar // Create basic block to hold stuff that comes after switch 84416f23570999cac1fa13597386938450843003840Daniel Dunbar // statement. We also need to create a default block now so that 84516f23570999cac1fa13597386938450843003840Daniel Dunbar // explicit case ranges tests can have a place to jump to on 84616f23570999cac1fa13597386938450843003840Daniel Dunbar // failure. 84755e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar llvm::BasicBlock *DefaultBlock = createBasicBlock("sw.default"); 84816f23570999cac1fa13597386938450843003840Daniel Dunbar SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock); 84916f23570999cac1fa13597386938450843003840Daniel Dunbar CaseRangeBlock = DefaultBlock; 85051b09f2c528c8460b5465c676173324e44176d62Devang Patel 8510912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // Clear the insertion point to indicate we are in unreachable code. 8520912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar Builder.ClearInsertionPoint(); 853d28a80d64616b66c91d28bb4c08ca2d8c594de4eEli Friedman 854e9b8c0a38549692f1b8f688c05c35442fc620865Devang Patel // All break statements jump to NextBlock. If BreakContinueStack is non empty 855e9b8c0a38549692f1b8f688c05c35442fc620865Devang Patel // then reuse last ContinueBlock. 856f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest OuterContinue; 857e4b6d342c29d5cb9d311756100df1603810fa892Anders Carlsson if (!BreakContinueStack.empty()) 858f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall OuterContinue = BreakContinueStack.back().ContinueBlock; 859e4b6d342c29d5cb9d311756100df1603810fa892Anders Carlsson 860f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall BreakContinueStack.push_back(BreakContinue(SwitchExit, OuterContinue)); 86151b09f2c528c8460b5465c676173324e44176d62Devang Patel 86251b09f2c528c8460b5465c676173324e44176d62Devang Patel // Emit switch body. 86351b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getBody()); 8641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 865e4b6d342c29d5cb9d311756100df1603810fa892Anders Carlsson BreakContinueStack.pop_back(); 86651b09f2c528c8460b5465c676173324e44176d62Devang Patel 86716f23570999cac1fa13597386938450843003840Daniel Dunbar // Update the default block in case explicit case range tests have 86816f23570999cac1fa13597386938450843003840Daniel Dunbar // been chained on top. 86916f23570999cac1fa13597386938450843003840Daniel Dunbar SwitchInsn->setSuccessor(0, CaseRangeBlock); 8701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 871f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If a default was never emitted: 87216f23570999cac1fa13597386938450843003840Daniel Dunbar if (!DefaultBlock->getParent()) { 873f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If we have cleanups, emit the default block so that there's a 874f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // place to jump through the cleanups from. 875f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (ConditionScope.requiresCleanups()) { 876f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBlock(DefaultBlock); 877f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 878f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Otherwise, just forward the default block to the switch end. 879f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else { 880ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall DefaultBlock->replaceAllUsesWith(SwitchExit.getBlock()); 881f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall delete DefaultBlock; 882f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 88316f23570999cac1fa13597386938450843003840Daniel Dunbar } 88416f23570999cac1fa13597386938450843003840Daniel Dunbar 885ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall ConditionScope.ForceCleanup(); 886ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall 88716f23570999cac1fa13597386938450843003840Daniel Dunbar // Emit continuation. 888ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(SwitchExit.getBlock(), true); 88951b09f2c528c8460b5465c676173324e44176d62Devang Patel 89051b09f2c528c8460b5465c676173324e44176d62Devang Patel SwitchInsn = SavedSwitchInsn; 891c049e4f406a7f7179eba98659044a32508e53289Devang Patel CaseRangeBlock = SavedCRBlock; 89251b09f2c528c8460b5465c676173324e44176d62Devang Patel} 893fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 8942819fa85651526d59ade4fdc9da2cadd7b132973Chris Lattnerstatic std::string 895444be7366d0a1e172c0290a1ea54c1cb16b5947cDaniel DunbarSimplifyConstraint(const char *Constraint, const TargetInfo &Target, 8962819fa85651526d59ade4fdc9da2cadd7b132973Chris Lattner llvm::SmallVectorImpl<TargetInfo::ConstraintInfo> *OutCons=0) { 897fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Result; 8981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 899fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson while (*Constraint) { 900fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson switch (*Constraint) { 901fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson default: 9022f474ea9ef7505df5d092287c48c19974222293bJohn Thompson Result += Target.convertConstraint(*Constraint); 903fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 904fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Ignore these 905fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '*': 906fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '?': 907fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '!': 908ef44e1110711276ffffe4b22d4ba0cebd49cb330John Thompson case '=': // Will see this and the following in mult-alt constraints. 909ef44e1110711276ffffe4b22d4ba0cebd49cb330John Thompson case '+': 910ef44e1110711276ffffe4b22d4ba0cebd49cb330John Thompson break; 9112f474ea9ef7505df5d092287c48c19974222293bJohn Thompson case ',': 9122f474ea9ef7505df5d092287c48c19974222293bJohn Thompson Result += "|"; 913fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 914fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case 'g': 915fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += "imr"; 916fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 917300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson case '[': { 9182819fa85651526d59ade4fdc9da2cadd7b132973Chris Lattner assert(OutCons && 919300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson "Must pass output names to constraints with a symbolic name"); 920300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson unsigned Index; 9211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool result = Target.resolveSymbolicName(Constraint, 9222819fa85651526d59ade4fdc9da2cadd7b132973Chris Lattner &(*OutCons)[0], 9232819fa85651526d59ade4fdc9da2cadd7b132973Chris Lattner OutCons->size(), Index); 924cbf40f913aa2aa5de6e0540fed209405d00a2c69Chris Lattner assert(result && "Could not resolve symbolic name"); (void)result; 925300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson Result += llvm::utostr(Index); 926300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson break; 927300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson } 928fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 9291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 930fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraint++; 931fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 9321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 933fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson return Result; 934fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 935fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 93603117d1b2e32d18652401b12d9049871992bf3adRafael Espindola/// AddVariableConstraints - Look at AsmExpr and if it is a variable declared 93703117d1b2e32d18652401b12d9049871992bf3adRafael Espindola/// as using a particular register add that as a constraint that will be used 93803117d1b2e32d18652401b12d9049871992bf3adRafael Espindola/// in this asm stmt. 9390ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindolastatic std::string 94003117d1b2e32d18652401b12d9049871992bf3adRafael EspindolaAddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, 94103117d1b2e32d18652401b12d9049871992bf3adRafael Espindola const TargetInfo &Target, CodeGenModule &CGM, 94203117d1b2e32d18652401b12d9049871992bf3adRafael Espindola const AsmStmt &Stmt) { 9430ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola const DeclRefExpr *AsmDeclRef = dyn_cast<DeclRefExpr>(&AsmExpr); 9440ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola if (!AsmDeclRef) 9450ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola return Constraint; 9460ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola const ValueDecl &Value = *AsmDeclRef->getDecl(); 9470ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola const VarDecl *Variable = dyn_cast<VarDecl>(&Value); 9480ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola if (!Variable) 9490ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola return Constraint; 9500ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola AsmLabelAttr *Attr = Variable->getAttr<AsmLabelAttr>(); 9510ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola if (!Attr) 9520ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola return Constraint; 9530ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola llvm::StringRef Register = Attr->getLabel(); 954baf86955a9a390f2643a1ea9806832eb4a92f716Rafael Espindola assert(Target.isValidGCCRegisterName(Register)); 95533a53440eb025dc511b7dcb27dea8029cc28b34fRafael Espindola // FIXME: We should check which registers are compatible with "r" or "x". 95633a53440eb025dc511b7dcb27dea8029cc28b34fRafael Espindola if (Constraint != "r" && Constraint != "x") { 9570ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola CGM.ErrorUnsupported(&Stmt, "__asm__"); 9580ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola return Constraint; 9590ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola } 9600ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola return "{" + Register.str() + "}"; 9610ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola} 9620ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola 9636d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedmanllvm::Value* 9646d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli FriedmanCodeGenFunction::EmitAsmInputLValue(const AsmStmt &S, 9656d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman const TargetInfo::ConstraintInfo &Info, 9666d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman LValue InputValue, QualType InputType, 9676d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman std::string &ConstraintStr) { 968634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson llvm::Value *Arg; 9691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (Info.allowsRegister() || !Info.allowsMemory()) { 9706d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman if (!CodeGenFunction::hasAggregateLLVMType(InputType)) { 9716d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman Arg = EmitLoadOfLValue(InputValue, InputType).getScalarVal(); 972634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson } else { 9736d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman const llvm::Type *Ty = ConvertType(InputType); 974ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson uint64_t Size = CGM.getTargetData().getTypeSizeInBits(Ty); 975ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson if (Size <= 64 && llvm::isPowerOf2_64(Size)) { 976d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Ty = llvm::IntegerType::get(getLLVMContext(), Size); 977ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson Ty = llvm::PointerType::getUnqual(Ty); 9781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9796d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman Arg = Builder.CreateLoad(Builder.CreateBitCast(InputValue.getAddress(), 9806d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman Ty)); 981ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson } else { 9826d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman Arg = InputValue.getAddress(); 983ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson ConstraintStr += '*'; 984ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson } 985634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson } 986634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson } else { 9876d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman Arg = InputValue.getAddress(); 988634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson ConstraintStr += '*'; 989634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson } 9901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 991634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson return Arg; 992634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson} 993634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson 9946d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedmanllvm::Value* CodeGenFunction::EmitAsmInput(const AsmStmt &S, 9956d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman const TargetInfo::ConstraintInfo &Info, 9966d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman const Expr *InputExpr, 9976d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman std::string &ConstraintStr) { 9986d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman if (Info.allowsRegister() || !Info.allowsMemory()) 9996d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman if (!CodeGenFunction::hasAggregateLLVMType(InputExpr->getType())) 10006d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman return EmitScalarExpr(InputExpr); 10016d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman 10026d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman InputExpr = InputExpr->IgnoreParenNoopCasts(getContext()); 10036d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman LValue Dest = EmitLValue(InputExpr); 10046d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman return EmitAsmInputLValue(S, Info, Dest, InputExpr->getType(), ConstraintStr); 10056d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman} 10066d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman 100747fc7e93b6af9e6a967231133a2f4bc626eeed26Chris Lattner/// getAsmSrcLocInfo - Return the !srcloc metadata node to attach to an inline 10085d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner/// asm call instruction. The !srcloc MDNode contains a list of constant 10095d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner/// integers which are the source locations of the start of each line in the 10105d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner/// asm. 101147fc7e93b6af9e6a967231133a2f4bc626eeed26Chris Lattnerstatic llvm::MDNode *getAsmSrcLocInfo(const StringLiteral *Str, 101247fc7e93b6af9e6a967231133a2f4bc626eeed26Chris Lattner CodeGenFunction &CGF) { 10135d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner llvm::SmallVector<llvm::Value *, 8> Locs; 10145d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner // Add the location of the first line to the MDNode. 10155d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner Locs.push_back(llvm::ConstantInt::get(CGF.Int32Ty, 10165d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner Str->getLocStart().getRawEncoding())); 10175d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner llvm::StringRef StrVal = Str->getString(); 10185d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner if (!StrVal.empty()) { 10195d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner const SourceManager &SM = CGF.CGM.getContext().getSourceManager(); 10205d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner const LangOptions &LangOpts = CGF.CGM.getLangOptions(); 10215d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner 10225d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner // Add the location of the start of each subsequent line of the asm to the 10235d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner // MDNode. 10245d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner for (unsigned i = 0, e = StrVal.size()-1; i != e; ++i) { 10255d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner if (StrVal[i] != '\n') continue; 10265d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner SourceLocation LineLoc = Str->getLocationOfByte(i+1, SM, LangOpts, 10275d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner CGF.Target); 10285d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner Locs.push_back(llvm::ConstantInt::get(CGF.Int32Ty, 10295d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner LineLoc.getRawEncoding())); 10305d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner } 10315d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner } 10325d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner 10335d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner return llvm::MDNode::get(CGF.getLLVMContext(), Locs.data(), Locs.size()); 103447fc7e93b6af9e6a967231133a2f4bc626eeed26Chris Lattner} 103547fc7e93b6af9e6a967231133a2f4bc626eeed26Chris Lattner 1036fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlssonvoid CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { 1037458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner // Analyze the asm string to decompose it into its pieces. We know that Sema 1038458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner // has already done this, so it is guaranteed to be successful. 1039458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner llvm::SmallVector<AsmStmt::AsmStringPiece, 4> Pieces; 1040fb5058ef67c054296c88db18ab1b3717845cb71dChris Lattner unsigned DiagOffs; 1041fb5058ef67c054296c88db18ab1b3717845cb71dChris Lattner S.AnalyzeAsmString(Pieces, getContext(), DiagOffs); 10421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1043458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner // Assemble the pieces into the final asm string. 1044458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner std::string AsmString; 1045458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner for (unsigned i = 0, e = Pieces.size(); i != e; ++i) { 1046458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner if (Pieces[i].isString()) 1047458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner AsmString += Pieces[i].getString(); 1048458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner else if (Pieces[i].getModifier() == '\0') 1049458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner AsmString += '$' + llvm::utostr(Pieces[i].getOperandNo()); 1050458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner else 1051458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner AsmString += "${" + llvm::utostr(Pieces[i].getOperandNo()) + ':' + 1052458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner Pieces[i].getModifier() + '}'; 1053281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar } 10541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1055481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner // Get all the output and input constraints together. 1056481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner llvm::SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos; 1057481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner llvm::SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos; 1058481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner 10591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) { 1060481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner TargetInfo::ConstraintInfo Info(S.getOutputConstraint(i), 1061481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner S.getOutputName(i)); 1062b992259f7790d3fb9fc5c2eb7182d7af9d64f9acChris Lattner bool IsValid = Target.validateOutputConstraint(Info); (void)IsValid; 1063b992259f7790d3fb9fc5c2eb7182d7af9d64f9acChris Lattner assert(IsValid && "Failed to parse output constraint"); 1064481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner OutputConstraintInfos.push_back(Info); 10651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 10661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1067481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) { 1068481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner TargetInfo::ConstraintInfo Info(S.getInputConstraint(i), 1069481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner S.getInputName(i)); 1070b992259f7790d3fb9fc5c2eb7182d7af9d64f9acChris Lattner bool IsValid = Target.validateInputConstraint(OutputConstraintInfos.data(), 1071b992259f7790d3fb9fc5c2eb7182d7af9d64f9acChris Lattner S.getNumOutputs(), Info); 1072b992259f7790d3fb9fc5c2eb7182d7af9d64f9acChris Lattner assert(IsValid && "Failed to parse input constraint"); (void)IsValid; 1073481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner InputConstraintInfos.push_back(Info); 1074481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner } 10751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1076fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Constraints; 10771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1078ede9d900809c4fd0298d52f5a63088ecb8302275Chris Lattner std::vector<LValue> ResultRegDests; 1079ede9d900809c4fd0298d52f5a63088ecb8302275Chris Lattner std::vector<QualType> ResultRegQualTys; 1080a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner std::vector<const llvm::Type *> ResultRegTypes; 1081a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner std::vector<const llvm::Type *> ResultTruncRegTypes; 1082fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::vector<const llvm::Type*> ArgTypes; 1083fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::vector<llvm::Value*> Args; 1084f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 1085f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // Keep track of inout constraints. 1086f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::string InOutConstraints; 1087f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::vector<llvm::Value*> InOutArgs; 1088f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::vector<const llvm::Type*> InOutArgTypes; 108903eb543cf7ebee463b33b5802b83ac92c21770cfAnders Carlsson 10901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) { 1091481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i]; 109203eb543cf7ebee463b33b5802b83ac92c21770cfAnders Carlsson 1093fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Simplify the output constraint. 1094481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner std::string OutputConstraint(S.getOutputConstraint(i)); 1095a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1, Target); 10961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1097810f6d5d6223adaab0ccf0139f40de6484ad1bb5Chris Lattner const Expr *OutExpr = S.getOutputExpr(i); 1098810f6d5d6223adaab0ccf0139f40de6484ad1bb5Chris Lattner OutExpr = OutExpr->IgnoreParenNoopCasts(getContext()); 10991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 110003117d1b2e32d18652401b12d9049871992bf3adRafael Espindola OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr, Target, 11010ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola CGM, S); 11020ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola 1103810f6d5d6223adaab0ccf0139f40de6484ad1bb5Chris Lattner LValue Dest = EmitLValue(OutExpr); 1104ede9d900809c4fd0298d52f5a63088ecb8302275Chris Lattner if (!Constraints.empty()) 1105bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson Constraints += ','; 1106bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson 1107a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // If this is a register output, then make the inline asm return it 1108a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // by-value. If this is a memory result, return the value by-reference. 1109ede9d900809c4fd0298d52f5a63088ecb8302275Chris Lattner if (!Info.allowsMemory() && !hasAggregateLLVMType(OutExpr->getType())) { 1110a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner Constraints += "=" + OutputConstraint; 1111ede9d900809c4fd0298d52f5a63088ecb8302275Chris Lattner ResultRegQualTys.push_back(OutExpr->getType()); 1112ede9d900809c4fd0298d52f5a63088ecb8302275Chris Lattner ResultRegDests.push_back(Dest); 1113a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner ResultRegTypes.push_back(ConvertTypeForMem(OutExpr->getType())); 1114a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner ResultTruncRegTypes.push_back(ResultRegTypes.back()); 11151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1116a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // If this output is tied to an input, and if the input is larger, then 1117a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // we need to set the actual result type of the inline asm node to be the 1118a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // same as the input type. 1119a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner if (Info.hasMatchingInput()) { 1120ebfc9857de58a326c84629915d9ffe3f36d8cc26Chris Lattner unsigned InputNo; 1121ebfc9857de58a326c84629915d9ffe3f36d8cc26Chris Lattner for (InputNo = 0; InputNo != S.getNumInputs(); ++InputNo) { 1122ebfc9857de58a326c84629915d9ffe3f36d8cc26Chris Lattner TargetInfo::ConstraintInfo &Input = InputConstraintInfos[InputNo]; 1123aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner if (Input.hasTiedOperand() && Input.getTiedOperand() == i) 1124a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner break; 1125ebfc9857de58a326c84629915d9ffe3f36d8cc26Chris Lattner } 1126ebfc9857de58a326c84629915d9ffe3f36d8cc26Chris Lattner assert(InputNo != S.getNumInputs() && "Didn't find matching input!"); 11271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1128a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner QualType InputTy = S.getInputExpr(InputNo)->getType(); 1129aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner QualType OutputType = OutExpr->getType(); 11301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1131a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner uint64_t InputSize = getContext().getTypeSize(InputTy); 1132aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner if (getContext().getTypeSize(OutputType) < InputSize) { 1133aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner // Form the asm to return the value as a larger integer or fp type. 1134aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner ResultRegTypes.back() = ConvertType(InputTy); 1135a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner } 1136a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner } 1137f6e2c2039f76fa58799f6d155892d54fc95755e1Dale Johannesen if (const llvm::Type* AdjTy = 1138f6e2c2039f76fa58799f6d155892d54fc95755e1Dale Johannesen Target.adjustInlineAsmType(OutputConstraint, ResultRegTypes.back(), 1139d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall getLLVMContext())) 1140f6e2c2039f76fa58799f6d155892d54fc95755e1Dale Johannesen ResultRegTypes.back() = AdjTy; 1141fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 1142fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ArgTypes.push_back(Dest.getAddress()->getType()); 1143cad3ab611ebd3bee3ce6395d649640047f904cdeAnders Carlsson Args.push_back(Dest.getAddress()); 1144f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Constraints += "=*"; 1145fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += OutputConstraint; 1146f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 11471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 114844def070435a2b5d67f0534f7a3a85a7389d60f2Chris Lattner if (Info.isReadWrite()) { 1149f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutConstraints += ','; 1150634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson 1151fca9361839ecc53224c764517e62fc0e15166004Anders Carlsson const Expr *InputExpr = S.getOutputExpr(i); 11526d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman llvm::Value *Arg = EmitAsmInputLValue(S, Info, Dest, InputExpr->getType(), 11536d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman InOutConstraints); 11541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 115544def070435a2b5d67f0534f7a3a85a7389d60f2Chris Lattner if (Info.allowsRegister()) 11569f2505b934745b18d580ade4dac7b8b16952a30cAnders Carlsson InOutConstraints += llvm::utostr(i); 11579f2505b934745b18d580ade4dac7b8b16952a30cAnders Carlsson else 11589f2505b934745b18d580ade4dac7b8b16952a30cAnders Carlsson InOutConstraints += OutputConstraint; 11592763b3af0a527c3a63cb058b90c22db0b7bcf558Anders Carlsson 1160fca9361839ecc53224c764517e62fc0e15166004Anders Carlsson InOutArgTypes.push_back(Arg->getType()); 1161fca9361839ecc53224c764517e62fc0e15166004Anders Carlsson InOutArgs.push_back(Arg); 1162f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 1163fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 11641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1165fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson unsigned NumConstraints = S.getNumOutputs() + S.getNumInputs(); 11661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1167fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) { 1168fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const Expr *InputExpr = S.getInputExpr(i); 1169fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1170481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i]; 1171481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner 1172ede9d900809c4fd0298d52f5a63088ecb8302275Chris Lattner if (!Constraints.empty()) 1173fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 11741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1175fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Simplify the input constraint. 1176481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner std::string InputConstraint(S.getInputConstraint(i)); 1177300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson InputConstraint = SimplifyConstraint(InputConstraint.c_str(), Target, 11782819fa85651526d59ade4fdc9da2cadd7b132973Chris Lattner &OutputConstraintInfos); 1179fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 11800ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola InputConstraint = 118103117d1b2e32d18652401b12d9049871992bf3adRafael Espindola AddVariableConstraints(InputConstraint, 11820ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola *InputExpr->IgnoreParenNoopCasts(getContext()), 11830ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola Target, CGM, S); 11840ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola 1185634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson llvm::Value *Arg = EmitAsmInput(S, Info, InputExpr, Constraints); 11861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11874df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner // If this input argument is tied to a larger output result, extend the 11884df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner // input to be the same size as the output. The LLVM backend wants to see 11894df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner // the input and output of a matching constraint be the same size. Note 11904df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner // that GCC does not define what the top bits are here. We use zext because 11914df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner // that is usually cheaper, but LLVM IR should really get an anyext someday. 11924df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner if (Info.hasTiedOperand()) { 11934df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner unsigned Output = Info.getTiedOperand(); 1194aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner QualType OutputType = S.getOutputExpr(Output)->getType(); 11954df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner QualType InputTy = InputExpr->getType(); 11961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1197aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner if (getContext().getTypeSize(OutputType) > 11984df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner getContext().getTypeSize(InputTy)) { 11994df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner // Use ptrtoint as appropriate so that we can do our extension. 12004df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner if (isa<llvm::PointerType>(Arg->getType())) 120177b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Arg = Builder.CreatePtrToInt(Arg, IntPtrTy); 1202aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner const llvm::Type *OutputTy = ConvertType(OutputType); 1203aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner if (isa<llvm::IntegerType>(OutputTy)) 1204aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner Arg = Builder.CreateZExt(Arg, OutputTy); 1205aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner else 1206aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner Arg = Builder.CreateFPExt(Arg, OutputTy); 12074df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner } 12084df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner } 1209f6e2c2039f76fa58799f6d155892d54fc95755e1Dale Johannesen if (const llvm::Type* AdjTy = 1210f6e2c2039f76fa58799f6d155892d54fc95755e1Dale Johannesen Target.adjustInlineAsmType(InputConstraint, Arg->getType(), 1211d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall getLLVMContext())) 1212f6e2c2039f76fa58799f6d155892d54fc95755e1Dale Johannesen Arg = Builder.CreateBitCast(Arg, AdjTy); 12131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1214fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ArgTypes.push_back(Arg->getType()); 1215fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Args.push_back(Arg); 1216fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += InputConstraint; 1217fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 12181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1219f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // Append the "input" part of inout constraints last. 1220f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { 1221f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson ArgTypes.push_back(InOutArgTypes[i]); 1222f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Args.push_back(InOutArgs[i]); 1223f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 1224f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Constraints += InOutConstraints; 12251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1226fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Clobbers 1227fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) { 122883c021c6d33aa173cf1a6e3bc61006dabb042703Anders Carlsson llvm::StringRef Clobber = S.getClobber(i)->getString(); 1229fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 123083c021c6d33aa173cf1a6e3bc61006dabb042703Anders Carlsson Clobber = Target.getNormalizedGCCRegisterName(Clobber); 12311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1232ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson if (i != 0 || NumConstraints != 0) 1233fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 12341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1235ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson Constraints += "~{"; 1236fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += Clobber; 1237ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson Constraints += '}'; 1238fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 12391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1240fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Add machine specific clobbers 1241ccf614c479ac93326a01e7b373b30759eed7807fEli Friedman std::string MachineClobbers = Target.getClobbers(); 1242ccf614c479ac93326a01e7b373b30759eed7807fEli Friedman if (!MachineClobbers.empty()) { 1243fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (!Constraints.empty()) 1244fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 1245ccf614c479ac93326a01e7b373b30759eed7807fEli Friedman Constraints += MachineClobbers; 1246fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 1247bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson 1248bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson const llvm::Type *ResultType; 1249a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner if (ResultRegTypes.empty()) 1250d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall ResultType = llvm::Type::getVoidTy(getLLVMContext()); 1251a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner else if (ResultRegTypes.size() == 1) 1252a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner ResultType = ResultRegTypes[0]; 1253bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson else 1254d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall ResultType = llvm::StructType::get(getLLVMContext(), ResultRegTypes); 12551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const llvm::FunctionType *FTy = 1257fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::FunctionType::get(ResultType, ArgTypes, false); 12581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::InlineAsm *IA = 12601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::InlineAsm::get(FTy, AsmString, Constraints, 1261fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.isVolatile() || S.getNumOutputs() == 0); 1262bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson llvm::CallInst *Result = Builder.CreateCall(IA, Args.begin(), Args.end()); 1263bc0822bad87ac4d2dcac8e1b71960301656a2699Anders Carlsson Result->addAttribute(~0, llvm::Attribute::NoUnwind); 12641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1265fc1a9c312d249a2c7458f763f848ba42685c23f8Chris Lattner // Slap the source location of the inline asm into a !srcloc metadata on the 1266fc1a9c312d249a2c7458f763f848ba42685c23f8Chris Lattner // call. 126747fc7e93b6af9e6a967231133a2f4bc626eeed26Chris Lattner Result->setMetadata("srcloc", getAsmSrcLocInfo(S.getAsmString(), *this)); 12681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1269a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // Extract all of the register value results from the asm. 1270a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner std::vector<llvm::Value*> RegResults; 1271a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner if (ResultRegTypes.size() == 1) { 1272a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner RegResults.push_back(Result); 1273bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson } else { 1274a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner for (unsigned i = 0, e = ResultRegTypes.size(); i != e; ++i) { 1275bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson llvm::Value *Tmp = Builder.CreateExtractValue(Result, i, "asmresult"); 1276a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner RegResults.push_back(Tmp); 1277a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner } 1278a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner } 12791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1280a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner for (unsigned i = 0, e = RegResults.size(); i != e; ++i) { 1281a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner llvm::Value *Tmp = RegResults[i]; 12821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1283a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // If the result type of the LLVM IR asm doesn't match the result type of 1284a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // the expression, do the conversion. 1285a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner if (ResultRegTypes[i] != ResultTruncRegTypes[i]) { 1286a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner const llvm::Type *TruncTy = ResultTruncRegTypes[i]; 1287aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner 1288aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner // Truncate the integer result to the right size, note that TruncTy can be 1289aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner // a pointer. 1290aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner if (TruncTy->isFloatingPointTy()) 1291aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner Tmp = Builder.CreateFPTrunc(Tmp, TruncTy); 12922dca88fc6d3e606a8131712be1800e3a4b90ca3eDan Gohman else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) { 1293aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner uint64_t ResSize = CGM.getTargetData().getTypeSizeInBits(TruncTy); 1294d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Tmp = Builder.CreateTrunc(Tmp, 1295d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::IntegerType::get(getLLVMContext(), (unsigned)ResSize)); 1296a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner Tmp = Builder.CreateIntToPtr(Tmp, TruncTy); 12972dca88fc6d3e606a8131712be1800e3a4b90ca3eDan Gohman } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) { 12982dca88fc6d3e606a8131712be1800e3a4b90ca3eDan Gohman uint64_t TmpSize =CGM.getTargetData().getTypeSizeInBits(Tmp->getType()); 1299d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Tmp = Builder.CreatePtrToInt(Tmp, 1300d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::IntegerType::get(getLLVMContext(), (unsigned)TmpSize)); 13012dca88fc6d3e606a8131712be1800e3a4b90ca3eDan Gohman Tmp = Builder.CreateTrunc(Tmp, TruncTy); 13022dca88fc6d3e606a8131712be1800e3a4b90ca3eDan Gohman } else if (TruncTy->isIntegerTy()) { 13032dca88fc6d3e606a8131712be1800e3a4b90ca3eDan Gohman Tmp = Builder.CreateTrunc(Tmp, TruncTy); 1304f6e2c2039f76fa58799f6d155892d54fc95755e1Dale Johannesen } else if (TruncTy->isVectorTy()) { 1305f6e2c2039f76fa58799f6d155892d54fc95755e1Dale Johannesen Tmp = Builder.CreateBitCast(Tmp, TruncTy); 1306a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner } 1307bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson } 13081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1309a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner EmitStoreThroughLValue(RValue::get(Tmp), ResultRegDests[i], 1310a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner ResultRegQualTys[i]); 1311bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson } 1312fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 1313