CGStmt.cpp revision fdc5d565b30bd2009ec98aac4b5846a740aff767
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" 174b93d660c6326ec79b5e369317d1051cf826c2f3Peter Collingbourne#include "TargetInfo.h" 18de7fb8413b13651fd85b7125d08b3c9ac2816d9dDaniel Dunbar#include "clang/AST/StmtVisitor.h" 197d22bf00dbabca86ba791f56a99e006181fa22ddChris Lattner#include "clang/Basic/PrettyStackTrace.h" 20fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson#include "clang/Basic/TargetInfo.h" 21fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson#include "llvm/ADT/StringExtras.h" 2217d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson#include "llvm/InlineAsm.h" 2317d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson#include "llvm/Intrinsics.h" 24ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson#include "llvm/Target/TargetData.h" 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace CodeGen; 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Statement Emission 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 320912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarvoid CodeGenFunction::EmitStopPoint(const Stmt *S) { 33e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson if (CGDebugInfo *DI = getDebugInfo()) { 3473fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher SourceLocation Loc; 3560e4fd95ed8c1f99697f4d9f73d07717b6e21048Devang Patel if (isa<DeclStmt>(S)) 3673fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher Loc = S->getLocEnd(); 3760e4fd95ed8c1f99697f4d9f73d07717b6e21048Devang Patel else 3873fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher Loc = S->getLocStart(); 3973fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher DI->EmitLocation(Builder, Loc); 400912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar } 410912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar} 420912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitStmt(const Stmt *S) { 445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(S && "Null statement?"); 45a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar 46f9aac38d1290c17192a74b5bc2de52b9fb1a87caEric Christopher // These statements have their own debug info handling. 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: 7428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley case Stmt::SEHExceptStmtClass: 7528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley case Stmt::SEHFinallyStmtClass: 76ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor case Stmt::MSDependentExistsStmtClass: 772a41637a995affa1563f4d82a8b026e326a2faa0John McCall llvm_unreachable("invalid statement class to emit generically"); 782a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::NullStmtClass: 792a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::CompoundStmtClass: 802a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::DeclStmtClass: 812a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::LabelStmtClass: 822a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::GotoStmtClass: 832a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::BreakStmtClass: 842a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::ContinueStmtClass: 852a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::DefaultStmtClass: 862a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::CaseStmtClass: 872a41637a995affa1563f4d82a8b026e326a2faa0John McCall llvm_unreachable("should have emitted these statements as simple"); 88cd5e60e1d4093b9a757cc85e35fccc093f8f8527Daniel Dunbar 892a41637a995affa1563f4d82a8b026e326a2faa0John McCall#define STMT(Type, Base) 902a41637a995affa1563f4d82a8b026e326a2faa0John McCall#define ABSTRACT_STMT(Op) 912a41637a995affa1563f4d82a8b026e326a2faa0John McCall#define EXPR(Type, Base) \ 922a41637a995affa1563f4d82a8b026e326a2faa0John McCall case Stmt::Type##Class: 932a41637a995affa1563f4d82a8b026e326a2faa0John McCall#include "clang/AST/StmtNodes.inc" 94cd5b22e12b6513163dd131589746c194090f14e6John McCall { 95cd5b22e12b6513163dd131589746c194090f14e6John McCall // Remember the block we came in on. 96cd5b22e12b6513163dd131589746c194090f14e6John McCall llvm::BasicBlock *incoming = Builder.GetInsertBlock(); 97cd5b22e12b6513163dd131589746c194090f14e6John McCall assert(incoming && "expression emission must have an insertion point"); 98cd5b22e12b6513163dd131589746c194090f14e6John McCall 992a41637a995affa1563f4d82a8b026e326a2faa0John McCall EmitIgnoredExpr(cast<Expr>(S)); 1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 101cd5b22e12b6513163dd131589746c194090f14e6John McCall llvm::BasicBlock *outgoing = Builder.GetInsertBlock(); 102cd5b22e12b6513163dd131589746c194090f14e6John McCall assert(outgoing && "expression emission cleared block!"); 103cd5b22e12b6513163dd131589746c194090f14e6John McCall 104cd5b22e12b6513163dd131589746c194090f14e6John McCall // The expression emitters assume (reasonably!) that the insertion 105cd5b22e12b6513163dd131589746c194090f14e6John McCall // point is always set. To maintain that, the call-emission code 106cd5b22e12b6513163dd131589746c194090f14e6John McCall // for noreturn functions has to enter a new block with no 107cd5b22e12b6513163dd131589746c194090f14e6John McCall // predecessors. We want to kill that block and mark the current 108cd5b22e12b6513163dd131589746c194090f14e6John McCall // insertion point unreachable in the common case of a call like 109cd5b22e12b6513163dd131589746c194090f14e6John McCall // "exit();". Since expression emission doesn't otherwise create 110cd5b22e12b6513163dd131589746c194090f14e6John McCall // blocks with no predecessors, we can just test for that. 111cd5b22e12b6513163dd131589746c194090f14e6John McCall // However, we must be careful not to do this to our incoming 112cd5b22e12b6513163dd131589746c194090f14e6John McCall // block, because *statement* emission does sometimes create 113cd5b22e12b6513163dd131589746c194090f14e6John McCall // reachable blocks which will have no predecessors until later in 114cd5b22e12b6513163dd131589746c194090f14e6John McCall // the function. This occurs with, e.g., labels that are not 115cd5b22e12b6513163dd131589746c194090f14e6John McCall // reachable by fallthrough. 116cd5b22e12b6513163dd131589746c194090f14e6John McCall if (incoming != outgoing && outgoing->use_empty()) { 117cd5b22e12b6513163dd131589746c194090f14e6John McCall outgoing->eraseFromParent(); 118cd5b22e12b6513163dd131589746c194090f14e6John McCall Builder.ClearInsertionPoint(); 1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 121cd5b22e12b6513163dd131589746c194090f14e6John McCall } 1222a41637a995affa1563f4d82a8b026e326a2faa0John McCall 1231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Stmt::IndirectGotoStmtClass: 1240ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar EmitIndirectGotoStmt(cast<IndirectGotoStmt>(*S)); break; 1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break; 1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break; 1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::DoStmtClass: EmitDoStmt(cast<DoStmt>(*S)); break; 1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::ForStmtClass: EmitForStmt(cast<ForStmt>(*S)); break; 1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break; 132a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar 13351b09f2c528c8460b5465c676173324e44176d62Devang Patel case Stmt::SwitchStmtClass: EmitSwitchStmt(cast<SwitchStmt>(*S)); break; 134fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case Stmt::AsmStmtClass: EmitAsmStmt(cast<AsmStmt>(*S)); break; 1350a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar 1360a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtTryStmtClass: 13764d5d6c5903157c521af496479d06dc26032d718Anders Carlsson EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S)); 1381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 1390a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtCatchStmtClass: 140b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable( 141b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie "@catch statements should be handled by EmitObjCAtTryStmt"); 1420a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtFinallyStmtClass: 143b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable( 144b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie "@finally statements should be handled by EmitObjCAtTryStmt"); 1450a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtThrowStmtClass: 14664d5d6c5903157c521af496479d06dc26032d718Anders Carlsson EmitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(*S)); 1470a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 1480a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtSynchronizedStmtClass: 14910cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattner EmitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(*S)); 1500a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Stmt::ObjCForCollectionStmtClass: 1523d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson EmitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(*S)); 1530a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 154f85e193739c953358c865005855253af4f68a497John McCall case Stmt::ObjCAutoreleasePoolStmtClass: 155f85e193739c953358c865005855253af4f68a497John McCall EmitObjCAutoreleasePoolStmt(cast<ObjCAutoreleasePoolStmt>(*S)); 156f85e193739c953358c865005855253af4f68a497John McCall break; 1576815e941998659a55c20c147861b0f437928c3d8Anders Carlsson 1586815e941998659a55c20c147861b0f437928c3d8Anders Carlsson case Stmt::CXXTryStmtClass: 1596815e941998659a55c20c147861b0f437928c3d8Anders Carlsson EmitCXXTryStmt(cast<CXXTryStmt>(*S)); 1606815e941998659a55c20c147861b0f437928c3d8Anders Carlsson break; 161ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith case Stmt::CXXForRangeStmtClass: 162ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith EmitCXXForRangeStmt(cast<CXXForRangeStmt>(*S)); 16328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley case Stmt::SEHTryStmtClass: 16428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley // FIXME Not yet implemented 165ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith break; 1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1690912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarbool CodeGenFunction::EmitSimpleStmt(const Stmt *S) { 1700912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar switch (S->getStmtClass()) { 1710912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar default: return false; 1720912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::NullStmtClass: break; 1730912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break; 174d286f05f1234bac289173f0eed88d7ecbaea0099Daniel Dunbar case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break; 1750912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break; 1760912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break; 1770912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::BreakStmtClass: EmitBreakStmt(cast<BreakStmt>(*S)); break; 1780912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::ContinueStmtClass: EmitContinueStmt(cast<ContinueStmt>(*S)); break; 1790912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::DefaultStmtClass: EmitDefaultStmt(cast<DefaultStmt>(*S)); break; 1800912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::CaseStmtClass: EmitCaseStmt(cast<CaseStmt>(*S)); break; 1810912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar } 1820912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 1830912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar return true; 1840912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar} 1850912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 1863379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true, 1873379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// this captures the expression result of the last sub-statement and returns it 1883379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// (for use by the statement expression extension). 1899b65551d0b387a7597fb39356a4d8ef10046445eChris LattnerRValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, 190558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall AggValueSlot AggSlot) { 1917d22bf00dbabca86ba791f56a99e006181fa22ddChris Lattner PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),S.getLBracLoc(), 1927d22bf00dbabca86ba791f56a99e006181fa22ddChris Lattner "LLVM IR generation of compound statement ('{}')"); 1931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 194fdc5d565b30bd2009ec98aac4b5846a740aff767Eric Christopher // Keep track of the current cleanup stack depth, including debug scopes. 195fdc5d565b30bd2009ec98aac4b5846a740aff767Eric Christopher LexicalScope Scope(*this, S.getSourceRange()); 1961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1973379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner for (CompoundStmt::const_body_iterator I = S.body_begin(), 1983379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner E = S.body_end()-GetLast; I != E; ++I) 1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(*I); 200e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv 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 278777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCallvoid CodeGenFunction::EmitBlockAfterUses(llvm::BasicBlock *block) { 279777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall bool inserted = false; 280777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall for (llvm::BasicBlock::use_iterator 281777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall i = block->use_begin(), e = block->use_end(); i != e; ++i) { 282777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall if (llvm::Instruction *insn = dyn_cast<llvm::Instruction>(*i)) { 283777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall CurFn->getBasicBlockList().insertAfter(insn->getParent(), block); 284777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall inserted = true; 285777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall break; 286777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall } 287777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall } 288777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall 289777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall if (!inserted) 290777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall CurFn->getBasicBlockList().push_back(block); 291777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall 292777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall Builder.SetInsertPoint(block); 293777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall} 294777d6e56ad9b1fed9866daf3ee6486d85c5b7d32John McCall 295f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallCodeGenFunction::JumpDest 296ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris LattnerCodeGenFunction::getJumpDestForLabel(const LabelDecl *D) { 297ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner JumpDest &Dest = LabelMap[D]; 298ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall if (Dest.isValid()) return Dest; 299f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 300f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Create, but don't insert, the new block. 301ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner Dest = JumpDest(createBasicBlock(D->getName()), 302ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EHScopeStack::stable_iterator::invalid(), 303ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall NextCleanupDestIndex++); 304f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall return Dest; 305f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall} 306f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 307ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattnervoid CodeGenFunction::EmitLabel(const LabelDecl *D) { 308ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner JumpDest &Dest = LabelMap[D]; 309f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 310ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall // If we didn't need a forward reference to this label, just go 311f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // ahead and create a destination at the current scope. 312ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall if (!Dest.isValid()) { 313ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner Dest = getJumpDestInCurrentScope(D->getName()); 314f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 315f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Otherwise, we need to give this label a target depth and remove 316f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // it from the branch-fixups list. 317f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else { 318ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall assert(!Dest.getScopeDepth().isValid() && "already emitted label!"); 319ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall Dest = JumpDest(Dest.getBlock(), 320ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EHStack.stable_begin(), 321ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall Dest.getDestIndex()); 322f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 323ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall ResolveBranchFixups(Dest.getBlock()); 324f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 325f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 326ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(Dest.getBlock()); 32791d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner} 32891d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner 32991d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner 33091d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattnervoid CodeGenFunction::EmitLabelStmt(const LabelStmt &S) { 331ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner EmitLabel(S.getDecl()); 3325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getSubStmt()); 3335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitGotoStmt(const GotoStmt &S) { 3360912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // If this code is reachable then emit a stop point (if generating 3370912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // debug info). We have to do this ourselves because we are on the 3380912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // "simple" statement path. 3390912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (HaveInsertPoint()) 3400912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(&S); 34136a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump 342f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBranchThroughCleanup(getJumpDestForLabel(S.getLabel())); 3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3453d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner 3460ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbarvoid CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) { 347ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner if (const LabelDecl *Target = S.getConstantTarget()) { 34895c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall EmitBranchThroughCleanup(getJumpDestForLabel(Target)); 34995c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall return; 35095c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall } 35195c225de9fa3d79f70ef5008c0279580a7d9dcadJohn McCall 35249c952f853fe2d15dd9c9ff2a29c696bd18fca13Chris Lattner // Ensure that we have an i8* for our PHI node. 353d9becd1846e2c72bf6ad283faa1b048f33dd3afeChris Lattner llvm::Value *V = Builder.CreateBitCast(EmitScalarExpr(S.getTarget()), 354d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Int8PtrTy, "addr"); 3553d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); 3563d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner 3573d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner 3583d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner // Get the basic block for the indirect goto. 3593d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner llvm::BasicBlock *IndGotoBB = GetIndirectGotoBlock(); 3603d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner 3613d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner // The first instruction in the block has to be the PHI for the switch dest, 3623d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner // add an entry for this branch. 3633d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner cast<llvm::PHINode>(IndGotoBB->begin())->addIncoming(V, CurBB); 3643d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner 3653d00fdc82fd550ae4bfbb2e700a1fc85bbd6d6fdChris Lattner EmitBranch(IndGotoBB); 3660ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar} 3670ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar 36862b72f642207ba2ba433d686df924dc9594e9897Chris Lattnervoid CodeGenFunction::EmitIfStmt(const IfStmt &S) { 3695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.4.1: The first substatement is executed if the expression compares 3705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // unequal to 0. The condition must be a scalar type. 371f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ConditionScope(*this); 37201234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor 3738cfe5a784133d90bf329fd20801824a6f71bb8caDouglas Gregor if (S.getConditionVariable()) 374b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall EmitAutoVarDecl(*S.getConditionVariable()); 3751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3769bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // If the condition constant folds and can be elided, try to avoid emitting 3779bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // the condition and the dead arm of the if/else. 378c2c90011a688c04a4e980282f08c267e081c4b00Chris Lattner bool CondConstant; 379c2c90011a688c04a4e980282f08c267e081c4b00Chris Lattner if (ConstantFoldsToSimpleInteger(S.getCond(), CondConstant)) { 38062b72f642207ba2ba433d686df924dc9594e9897Chris Lattner // Figure out which block (then or else) is executed. 381c2c90011a688c04a4e980282f08c267e081c4b00Chris Lattner const Stmt *Executed = S.getThen(); 382c2c90011a688c04a4e980282f08c267e081c4b00Chris Lattner const Stmt *Skipped = S.getElse(); 383c2c90011a688c04a4e980282f08c267e081c4b00Chris Lattner if (!CondConstant) // Condition false? 38462b72f642207ba2ba433d686df924dc9594e9897Chris Lattner std::swap(Executed, Skipped); 3851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 38662b72f642207ba2ba433d686df924dc9594e9897Chris Lattner // If the skipped block has no labels in it, just emit the executed block. 38762b72f642207ba2ba433d686df924dc9594e9897Chris Lattner // This avoids emitting dead code and simplifies the CFG substantially. 3889bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner if (!ContainsLabel(Skipped)) { 38901234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor if (Executed) { 390f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ExecutedScope(*this); 39162b72f642207ba2ba433d686df924dc9594e9897Chris Lattner EmitStmt(Executed); 39201234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor } 39362b72f642207ba2ba433d686df924dc9594e9897Chris Lattner return; 39462b72f642207ba2ba433d686df924dc9594e9897Chris Lattner } 39562b72f642207ba2ba433d686df924dc9594e9897Chris Lattner } 3969bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner 3979bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // Otherwise, the condition did not fold, or we couldn't elide it. Just emit 3989bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // the conditional branch. 399781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar llvm::BasicBlock *ThenBlock = createBasicBlock("if.then"); 400781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar llvm::BasicBlock *ContBlock = createBasicBlock("if.end"); 401781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar llvm::BasicBlock *ElseBlock = ContBlock; 4025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getElse()) 403781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar ElseBlock = createBasicBlock("if.else"); 404781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar EmitBranchOnBoolExpr(S.getCond(), ThenBlock, ElseBlock); 4051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the 'then' code. 40701234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor EmitBlock(ThenBlock); 40801234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor { 409f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ThenScope(*this); 41001234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor EmitStmt(S.getThen()); 41101234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor } 412d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(ContBlock); 4131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the 'else' code if present. 4155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (const Stmt *Else = S.getElse()) { 416acd723666777b4ac1f79a97b6a300e6cf919d519Devang Patel // There is no need to emit line number for unconditional branch. 417acd723666777b4ac1f79a97b6a300e6cf919d519Devang Patel if (getDebugInfo()) 418acd723666777b4ac1f79a97b6a300e6cf919d519Devang Patel Builder.SetCurrentDebugLocation(llvm::DebugLoc()); 4195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ElseBlock); 42001234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor { 421f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ElseScope(*this); 42201234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor EmitStmt(Else); 42301234bbc1cb94946df8046ad95e17537082b4f71Douglas Gregor } 424acd723666777b4ac1f79a97b6a300e6cf919d519Devang Patel // There is no need to emit line number for unconditional branch. 425acd723666777b4ac1f79a97b6a300e6cf919d519Devang Patel if (getDebugInfo()) 426acd723666777b4ac1f79a97b6a300e6cf919d519Devang Patel Builder.SetCurrentDebugLocation(llvm::DebugLoc()); 427d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(ContBlock); 4285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the continuation block for code after the if. 431c22d665ede76f70228055d638a087f4bd438292dDaniel Dunbar EmitBlock(ContBlock, true); 4325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitWhileStmt(const WhileStmt &S) { 435f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit the header for the loop, which will also become 436f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // the continue target. 437f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond"); 438ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(LoopHeader.getBlock()); 439f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 440f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Create an exit block for when the condition fails, which will 441f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // also become the break target. 442f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest LoopExit = getJumpDestInCurrentScope("while.end"); 44372cac2ccce8058833f56358e3391e28a8ddeeaa4Mike Stump 44472cac2ccce8058833f56358e3391e28a8ddeeaa4Mike Stump // Store the blocks to use for break and continue. 445f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall BreakContinueStack.push_back(BreakContinue(LoopExit, LoopHeader)); 4461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4475656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor // C++ [stmt.while]p2: 4485656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor // When the condition of a while statement is a declaration, the 4495656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor // scope of the variable that is declared extends from its point 4505656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor // of declaration (3.3.2) to the end of the while statement. 4515656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor // [...] 4525656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor // The object created in a condition is destroyed and created 4535656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor // with each iteration of the loop. 454f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ConditionScope(*this); 4555656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor 456f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (S.getConditionVariable()) 457b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall EmitAutoVarDecl(*S.getConditionVariable()); 4585656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor 45916b16206741f5139c4ad870632db8f9ea4c6c943Mike Stump // Evaluate the conditional in the while header. C99 6.8.5.1: The 46016b16206741f5139c4ad870632db8f9ea4c6c943Mike Stump // evaluation of the controlling expression takes place before each 46116b16206741f5139c4ad870632db8f9ea4c6c943Mike Stump // execution of the loop body. 4625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 4635656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor 4642c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel // while(1) is common, avoid extra exit blocks. Be sure 4655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // to correctly handle break/continue though. 4662c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel bool EmitBoolCondBranch = true; 4671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) 4682c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (C->isOne()) 4692c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel EmitBoolCondBranch = false; 4701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // As long as the condition is true, go to the loop body. 472f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *LoopBody = createBasicBlock("while.body"); 473f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (EmitBoolCondBranch) { 474ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); 475f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (ConditionScope.requiresCleanups()) 476f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ExitBlock = createBasicBlock("while.exit"); 477f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 478f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock); 479f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 480ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall if (ExitBlock != LoopExit.getBlock()) { 481f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBlock(ExitBlock); 482f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBranchThroughCleanup(LoopExit); 483f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 484f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 4855656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor 486f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit the loop body. We have to emit this in a cleanup scope 487f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // because it might be a singleton DeclStmt. 4885656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor { 489f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope BodyScope(*this); 4905656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor EmitBlock(LoopBody); 4915656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor EmitStmt(S.getBody()); 4925656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor } 493da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 4941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump BreakContinueStack.pop_back(); 4951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 496f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Immediately force cleanup. 497f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ConditionScope.ForceCleanup(); 4985656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor 499f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Branch to the loop header again. 500ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBranch(LoopHeader.getBlock()); 5011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the exit block. 503ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(LoopExit.getBlock(), true); 5045656e14d91405417182171a705ed3e3d2d6d7aa3Douglas Gregor 505aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar // The LoopHeader typically is just a branch if we skipped emitting 506aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar // a branch, try to erase it. 507f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (!EmitBoolCondBranch) 508ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall SimplifyForwardingBlocks(LoopHeader.getBlock()); 5095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 5105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitDoStmt(const DoStmt &S) { 512f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest LoopExit = getJumpDestInCurrentScope("do.end"); 513f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest LoopCond = getJumpDestInCurrentScope("do.cond"); 5141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 515da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 516f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall BreakContinueStack.push_back(BreakContinue(LoopExit, LoopCond)); 5171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 518f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Emit the body of the loop. 519f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall llvm::BasicBlock *LoopBody = createBasicBlock("do.body"); 520f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBlock(LoopBody); 521f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall { 522f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope BodyScope(*this); 523f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitStmt(S.getBody()); 524f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 5251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 526e4b6d342c29d5cb9d311756100df1603810fa892Anders Carlsson BreakContinueStack.pop_back(); 5271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 528ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(LoopCond.getBlock()); 5291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5.2: "The evaluation of the controlling expression takes place 5315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // after each execution of the loop body." 5321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the conditional in the while header. 5345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5p2/p4: The first substatement is executed if the expression 5355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // compares unequal to 0. The condition must be a scalar type. 5365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 53705f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 53805f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // "do {} while (0)" is common in macros, avoid extra blocks. Be sure 53905f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // to correctly handle break/continue though. 54005f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel bool EmitBoolCondBranch = true; 5411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) 54205f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (C->isZero()) 54305f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel EmitBoolCondBranch = false; 54405f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 5455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // As long as the condition is true, iterate the loop. 54605f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (EmitBoolCondBranch) 547ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall Builder.CreateCondBr(BoolCondVal, LoopBody, LoopExit.getBlock()); 5481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the exit block. 550ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(LoopExit.getBlock()); 55105f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 552aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar // The DoCond block typically is just a branch if we skipped 553aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar // emitting a branch, try to erase it. 554aa5bd87f1fd5f9ca47924248817c89325759b30eDaniel Dunbar if (!EmitBoolCondBranch) 555ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall SimplifyForwardingBlocks(LoopCond.getBlock()); 5565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 5575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitForStmt(const ForStmt &S) { 559f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest LoopExit = getJumpDestInCurrentScope("for.end"); 560f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 561f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ForScope(*this); 562da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 5630554e0e30d24d9ad7d5e12f8e7583ebb5c9715bfDevang Patel CGDebugInfo *DI = getDebugInfo(); 56473fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher if (DI) 56573fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin()); 5660554e0e30d24d9ad7d5e12f8e7583ebb5c9715bfDevang Patel 5675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the first part before the loop. 5685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getInit()) 5695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getInit()); 5705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Start the loop with a block that tests the condition. 572f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If there's an increment, the continue scope will be overwritten 573f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // later. 574f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest Continue = getJumpDestInCurrentScope("for.cond"); 575ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall llvm::BasicBlock *CondBlock = Continue.getBlock(); 5765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(CondBlock); 5775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 578d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor // Create a cleanup scope for the condition variable cleanups. 579f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ConditionScope(*this); 58099e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor 581d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor llvm::Value *BoolCondVal = 0; 5825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getCond()) { 58399e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor // If the for statement has a condition scope, emit the local variable 58499e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor // declaration. 585ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); 586d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor if (S.getConditionVariable()) { 587b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall EmitAutoVarDecl(*S.getConditionVariable()); 588d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor } 589f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 590f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If there are any cleanups between here and the loop-exit scope, 591f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // create a block to stage a loop exit along. 592f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (ForScope.requiresCleanups()) 593f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ExitBlock = createBasicBlock("for.cond.cleanup"); 59499e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor 59531a0984b5cb4af99d2407c0f25bf5af68df681c6Chris Lattner // As long as the condition is true, iterate the loop. 5969615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 5971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5p2/p4: The first substatement is executed if the expression 5995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // compares unequal to 0. The condition must be a scalar type. 600d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor BoolCondVal = EvaluateExprAsBool(S.getCond()); 601f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock); 602f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 603ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall if (ExitBlock != LoopExit.getBlock()) { 604f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBlock(ExitBlock); 605f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBranchThroughCleanup(LoopExit); 606f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 6071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump EmitBlock(ForBody); 6095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 6105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Treat it as a non-zero constant. Don't even create a new block for the 6115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // body, just fall into it. 6125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 6135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // If the for loop doesn't have an increment we can just use the 615f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // condition as the continue block. Otherwise we'll need to create 616f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // a block for it (in the current scope, i.e. in the scope of the 617f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // condition), and that we will become our continue block. 618da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner if (S.getInc()) 619f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall Continue = getJumpDestInCurrentScope("for.inc"); 6201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 621da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 622f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); 6233e9da66ac7e88d64d30ee777588677320660cf84Mike Stump 624d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor { 625d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor // Create a separate cleanup scope for the body, in case it is not 626d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor // a compound statement. 627f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope BodyScope(*this); 628d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor EmitStmt(S.getBody()); 629d975206755e26a391f4a1cd8bf8f96a6a65b05e6Douglas Gregor } 630da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 6315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If there is an increment, emit it next. 632ad12b6d643aba6c36f5cec4c9beb4977a12eace4Daniel Dunbar if (S.getInc()) { 633ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(Continue.getBlock()); 634883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner EmitStmt(S.getInc()); 635ad12b6d643aba6c36f5cec4c9beb4977a12eace4Daniel Dunbar } 6361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 63745d3fe1898d3726d269a0bd2ccb8527102e29d79Douglas Gregor BreakContinueStack.pop_back(); 638f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 639f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ConditionScope.ForceCleanup(); 640f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBranch(CondBlock); 641f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 642f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall ForScope.ForceCleanup(); 643f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 64473fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher if (DI) 64573fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd()); 6465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 647da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Emit the fall-through block. 648ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(LoopExit.getBlock(), true); 6495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 6505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 651ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smithvoid CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S) { 652ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith JumpDest LoopExit = getJumpDestInCurrentScope("for.end"); 653ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 654ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith RunCleanupsScope ForScope(*this); 655ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 656ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith CGDebugInfo *DI = getDebugInfo(); 65773fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher if (DI) 65873fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin()); 659ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 660ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Evaluate the first pieces before the loop. 661ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith EmitStmt(S.getRangeStmt()); 662ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith EmitStmt(S.getBeginEndStmt()); 663ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 664ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Start the loop with a block that tests the condition. 665ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // If there's an increment, the continue scope will be overwritten 666ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // later. 667ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 668ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith EmitBlock(CondBlock); 669ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 670ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // If there are any cleanups between here and the loop-exit scope, 671ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // create a block to stage a loop exit along. 672ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); 673ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (ForScope.requiresCleanups()) 674ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith ExitBlock = createBasicBlock("for.cond.cleanup"); 675ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 676ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // The loop body, consisting of the specified body and the loop variable. 677ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 678ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 679ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // The body is executed if the expression, contextually converted 680ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // to bool, is true. 681ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 682ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock); 683ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 684ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (ExitBlock != LoopExit.getBlock()) { 685ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith EmitBlock(ExitBlock); 686ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith EmitBranchThroughCleanup(LoopExit); 687ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith } 688ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 689ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith EmitBlock(ForBody); 690ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 691ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Create a block for the increment. In case of a 'continue', we jump there. 692ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith JumpDest Continue = getJumpDestInCurrentScope("for.inc"); 693ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 694ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Store the blocks to use for break and continue. 695ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); 696ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 697ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith { 698ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Create a separate cleanup scope for the loop variable and body. 699ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith RunCleanupsScope BodyScope(*this); 700ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith EmitStmt(S.getLoopVarStmt()); 701ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith EmitStmt(S.getBody()); 702ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith } 703ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 704ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // If there is an increment, emit it next. 705ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith EmitBlock(Continue.getBlock()); 706ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith EmitStmt(S.getInc()); 707ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 708ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith BreakContinueStack.pop_back(); 709ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 710ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith EmitBranch(CondBlock); 711ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 712ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith ForScope.ForceCleanup(); 713ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 71473fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher if (DI) 71573fb35003aad027492e661a3749e921b5d1ecaf9Eric Christopher DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd()); 716ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 717ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Emit the fall-through block. 718ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith EmitBlock(LoopExit.getBlock(), true); 719ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith} 720ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 72129e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbarvoid CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) { 72229e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar if (RV.isScalar()) { 72329e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar Builder.CreateStore(RV.getScalarVal(), ReturnValue); 72429e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } else if (RV.isAggregate()) { 72529e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar EmitAggregateCopy(ReturnValue, RV.getAggregateAddr(), Ty); 72629e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } else { 72729e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false); 72829e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } 72982d8ef0be44ddba608c1ce5c8b6b48da83bc1821Anders Carlsson EmitBranchThroughCleanup(ReturnBlock); 73029e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar} 73129e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar 7325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand 7335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// if the function returns void, or may be missing one if the function returns 7345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// non-void. Fun stuff :). 7355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { 7365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the result value, even if unused, to evalute the side effects. 7375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const Expr *RV = S.getRetValue(); 7381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7395ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // FIXME: Clean this up by using an LValue for ReturnTemp, 7405ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // EmitStoreThroughLValue, and EmitAnyExpr. 741d86c477fb5d3fc34864afecbbb5443da9355e8fbDouglas Gregor if (S.getNRVOCandidate() && S.getNRVOCandidate()->isNRVOVariable() && 742d86c477fb5d3fc34864afecbbb5443da9355e8fbDouglas Gregor !Target.useGlobalsForAutomaticVariables()) { 743d86c477fb5d3fc34864afecbbb5443da9355e8fbDouglas Gregor // Apply the named return value optimization for this return statement, 744d86c477fb5d3fc34864afecbbb5443da9355e8fbDouglas Gregor // which means doing nothing: the appropriate result has already been 745d86c477fb5d3fc34864afecbbb5443da9355e8fbDouglas Gregor // constructed into the NRVO variable. 7463d91bbcdab155181556969cad6ec97014405acedDouglas Gregor 7473d91bbcdab155181556969cad6ec97014405acedDouglas Gregor // If there is an NRVO flag for this variable, set it to 1 into indicate 7483d91bbcdab155181556969cad6ec97014405acedDouglas Gregor // that the cleanup code should not destroy the variable. 749d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall if (llvm::Value *NRVOFlag = NRVOFlags[S.getNRVOCandidate()]) 750d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Builder.CreateStore(Builder.getTrue(), NRVOFlag); 751d86c477fb5d3fc34864afecbbb5443da9355e8fbDouglas Gregor } else if (!ReturnValue) { 7525ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // Make sure not to return anything, but evaluate the expression 7535ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // for side effects. 7545ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar if (RV) 755144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman EmitAnyExpr(RV); 7565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else if (RV == 0) { 7575ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // Do nothing (return value is left uninitialized) 758d54b6ac2f4f6f0bd0076cbfa885b57277066f06cEli Friedman } else if (FnRetTy->isReferenceType()) { 759d54b6ac2f4f6f0bd0076cbfa885b57277066f06cEli Friedman // If this function returns a reference, take the address of the expression 760d54b6ac2f4f6f0bd0076cbfa885b57277066f06cEli Friedman // rather than the value. 76132f36baa6c8d491c374af622b4e3ac28d597453cAnders Carlsson RValue Result = EmitReferenceBindingToExpr(RV, /*InitializedDecl=*/0); 76233fd1fc1814a5573c972840d49317989e20deaceDouglas Gregor Builder.CreateStore(Result.getScalarVal(), ReturnValue); 7634b0029d5f8742760981a3bd58004f75454090a61Chris Lattner } else if (!hasAggregateLLVMType(RV->getType())) { 7645ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar Builder.CreateStore(EmitScalarExpr(RV), ReturnValue); 7659b2dc287177394a8f73833e2ad4f7ca8cd6f22bbChris Lattner } else if (RV->getType()->isAnyComplexType()) { 7665ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar EmitComplexExprIntoAddr(RV, ReturnValue, false); 7675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 768d7722d9d76a851e7897f4127626616d3b1b8e530Eli Friedman CharUnits Alignment = getContext().getTypeAlignInChars(RV->getType()); 769f394078fde147dcf27e9b6a7965517388d64dcb6Eli Friedman EmitAggExpr(RV, AggValueSlot::forAddr(ReturnValue, Alignment, Qualifiers(), 7707c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall AggValueSlot::IsDestructed, 771410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::DoesNotNeedGCBarriers, 772410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::IsNotAliased)); 7735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 774144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman 77582d8ef0be44ddba608c1ce5c8b6b48da83bc1821Anders Carlsson EmitBranchThroughCleanup(ReturnBlock); 7765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 7775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitDeclStmt(const DeclStmt &S) { 7799198126067a447f8aaccf9fff09be294c8bcb81eDevang Patel // As long as debug info is modeled with instructions, we have to ensure we 7809198126067a447f8aaccf9fff09be294c8bcb81eDevang Patel // have a place to insert here and write the stop point here. 7819198126067a447f8aaccf9fff09be294c8bcb81eDevang Patel if (getDebugInfo() && HaveInsertPoint()) 7829198126067a447f8aaccf9fff09be294c8bcb81eDevang Patel EmitStopPoint(&S); 7839198126067a447f8aaccf9fff09be294c8bcb81eDevang Patel 784e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek for (DeclStmt::const_decl_iterator I = S.decl_begin(), E = S.decl_end(); 785e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek I != E; ++I) 786e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek EmitDecl(**I); 7876fa5f0943a84233b2e1ec9716eae55643225bfd4Chris Lattner} 788da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 7890912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarvoid CodeGenFunction::EmitBreakStmt(const BreakStmt &S) { 790da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!"); 791da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 7920912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // If this code is reachable then emit a stop point (if generating 7930912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // debug info). We have to do this ourselves because we are on the 7940912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // "simple" statement path. 7950912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (HaveInsertPoint()) 7960912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(&S); 797ec9771d57f94cc204491b3174e88069d08cdd684Mike Stump 798f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest Block = BreakContinueStack.back().BreakBlock; 79982d8ef0be44ddba608c1ce5c8b6b48da83bc1821Anders Carlsson EmitBranchThroughCleanup(Block); 800da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner} 801da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 8020912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarvoid CodeGenFunction::EmitContinueStmt(const ContinueStmt &S) { 803da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 804da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 8050912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // If this code is reachable then emit a stop point (if generating 8060912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // debug info). We have to do this ourselves because we are on the 8070912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // "simple" statement path. 8080912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (HaveInsertPoint()) 8090912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(&S); 810ec9771d57f94cc204491b3174e88069d08cdd684Mike Stump 811f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest Block = BreakContinueStack.back().ContinueBlock; 81282d8ef0be44ddba608c1ce5c8b6b48da83bc1821Anders Carlsson EmitBranchThroughCleanup(Block); 813da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner} 81451b09f2c528c8460b5465c676173324e44176d62Devang Patel 815c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// EmitCaseStmtRange - If case statement range is not too big then 816c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// add multiple cases to switch instruction, one for each value within 817c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// the range. If range is too big then emit "if" condition check. 818c049e4f406a7f7179eba98659044a32508e53289Devang Patelvoid CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) { 8194efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar assert(S.getRHS() && "Expected RHS value in CaseStmt"); 820c049e4f406a7f7179eba98659044a32508e53289Devang Patel 821a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith llvm::APSInt LHS = S.getLHS()->EvaluateKnownConstInt(getContext()); 822a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith llvm::APSInt RHS = S.getRHS()->EvaluateKnownConstInt(getContext()); 8234efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar 82416f23570999cac1fa13597386938450843003840Daniel Dunbar // Emit the code for this case. We do this first to make sure it is 82516f23570999cac1fa13597386938450843003840Daniel Dunbar // properly chained from our predecessor before generating the 82616f23570999cac1fa13597386938450843003840Daniel Dunbar // switch machinery to enter this block. 827f84dcda7e2ab2f6d5be5a8c52d22ef4c442dd762Daniel Dunbar EmitBlock(createBasicBlock("sw.bb")); 82816f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *CaseDest = Builder.GetInsertBlock(); 82916f23570999cac1fa13597386938450843003840Daniel Dunbar EmitStmt(S.getSubStmt()); 83016f23570999cac1fa13597386938450843003840Daniel Dunbar 8314efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar // If range is empty, do nothing. 8324efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar if (LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS)) 8334efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar return; 834c049e4f406a7f7179eba98659044a32508e53289Devang Patel 835c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::APInt Range = RHS - LHS; 83616f23570999cac1fa13597386938450843003840Daniel Dunbar // FIXME: parameters such as this should not be hardcoded. 837c049e4f406a7f7179eba98659044a32508e53289Devang Patel if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) { 838c049e4f406a7f7179eba98659044a32508e53289Devang Patel // Range is small enough to add multiple switch instruction cases. 8394efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar for (unsigned i = 0, e = Range.getZExtValue() + 1; i != e; ++i) { 84097d5437f48f8d935bf053915ab3d250edfe5fad5Chris Lattner SwitchInsn->addCase(Builder.getInt(LHS), CaseDest); 8412d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel LHS++; 8422d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel } 843c049e4f406a7f7179eba98659044a32508e53289Devang Patel return; 8441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 8451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 84616f23570999cac1fa13597386938450843003840Daniel Dunbar // The range is too big. Emit "if" condition into a new block, 84716f23570999cac1fa13597386938450843003840Daniel Dunbar // making sure to save and restore the current insertion point. 84816f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *RestoreBB = Builder.GetInsertBlock(); 84916f23570999cac1fa13597386938450843003840Daniel Dunbar 85016f23570999cac1fa13597386938450843003840Daniel Dunbar // Push this test onto the chain of range checks (which terminates 85116f23570999cac1fa13597386938450843003840Daniel Dunbar // in the default basic block). The switch's default will be changed 85216f23570999cac1fa13597386938450843003840Daniel Dunbar // to the top of this chain after switch emission is complete. 85316f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *FalseDest = CaseRangeBlock; 85455e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar CaseRangeBlock = createBasicBlock("sw.caserange"); 85516f23570999cac1fa13597386938450843003840Daniel Dunbar 85616f23570999cac1fa13597386938450843003840Daniel Dunbar CurFn->getBasicBlockList().push_back(CaseRangeBlock); 85716f23570999cac1fa13597386938450843003840Daniel Dunbar Builder.SetInsertPoint(CaseRangeBlock); 858c049e4f406a7f7179eba98659044a32508e53289Devang Patel 859c049e4f406a7f7179eba98659044a32508e53289Devang Patel // Emit range check. 8601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *Diff = 861578faa837b552403e2002b97fdfbfde14f2448e5Benjamin Kramer Builder.CreateSub(SwitchInsn->getCondition(), Builder.getInt(LHS)); 8621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::Value *Cond = 86397d5437f48f8d935bf053915ab3d250edfe5fad5Chris Lattner Builder.CreateICmpULE(Diff, Builder.getInt(Range), "inbounds"); 864c049e4f406a7f7179eba98659044a32508e53289Devang Patel Builder.CreateCondBr(Cond, CaseDest, FalseDest); 865c049e4f406a7f7179eba98659044a32508e53289Devang Patel 86616f23570999cac1fa13597386938450843003840Daniel Dunbar // Restore the appropriate insertion point. 867a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar if (RestoreBB) 868a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar Builder.SetInsertPoint(RestoreBB); 869a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar else 870a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar Builder.ClearInsertionPoint(); 871c049e4f406a7f7179eba98659044a32508e53289Devang Patel} 8722d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel 873c049e4f406a7f7179eba98659044a32508e53289Devang Patelvoid CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { 874d66715d83e64b6bfd0bddebe51874b1b7a64abefFariborz Jahanian // If there is no enclosing switch instance that we're aware of, then this 875d66715d83e64b6bfd0bddebe51874b1b7a64abefFariborz Jahanian // case statement and its block can be elided. This situation only happens 876d66715d83e64b6bfd0bddebe51874b1b7a64abefFariborz Jahanian // when we've constant-folded the switch, are emitting the constant case, 877d66715d83e64b6bfd0bddebe51874b1b7a64abefFariborz Jahanian // and part of the constant case includes another case statement. For 878d66715d83e64b6bfd0bddebe51874b1b7a64abefFariborz Jahanian // instance: switch (4) { case 4: do { case 5: } while (1); } 879303b4f946470a054cea8f91af54008aeb3c09507Fariborz Jahanian if (!SwitchInsn) { 880303b4f946470a054cea8f91af54008aeb3c09507Fariborz Jahanian EmitStmt(S.getSubStmt()); 881d66715d83e64b6bfd0bddebe51874b1b7a64abefFariborz Jahanian return; 882303b4f946470a054cea8f91af54008aeb3c09507Fariborz Jahanian } 883d66715d83e64b6bfd0bddebe51874b1b7a64abefFariborz Jahanian 884b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner // Handle case ranges. 885c049e4f406a7f7179eba98659044a32508e53289Devang Patel if (S.getRHS()) { 886c049e4f406a7f7179eba98659044a32508e53289Devang Patel EmitCaseStmtRange(S); 887c049e4f406a7f7179eba98659044a32508e53289Devang Patel return; 888c049e4f406a7f7179eba98659044a32508e53289Devang Patel } 8891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 89097d5437f48f8d935bf053915ab3d250edfe5fad5Chris Lattner llvm::ConstantInt *CaseVal = 891a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith Builder.getInt(S.getLHS()->EvaluateKnownConstInt(getContext())); 89297d5437f48f8d935bf053915ab3d250edfe5fad5Chris Lattner 893421048698b6b6bf86754190bcfe98a0ed82ee5b5Chris Lattner // If the body of the case is just a 'break', and if there was no fallthrough, 894421048698b6b6bf86754190bcfe98a0ed82ee5b5Chris Lattner // try to not emit an empty block. 895b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner if (isa<BreakStmt>(S.getSubStmt())) { 896b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner JumpDest Block = BreakContinueStack.back().BreakBlock; 897b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner 898b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner // Only do this optimization if there are no cleanups that need emitting. 899b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner if (isObviouslyBranchWithoutCleanups(Block)) { 90097d5437f48f8d935bf053915ab3d250edfe5fad5Chris Lattner SwitchInsn->addCase(CaseVal, Block.getBlock()); 901421048698b6b6bf86754190bcfe98a0ed82ee5b5Chris Lattner 902421048698b6b6bf86754190bcfe98a0ed82ee5b5Chris Lattner // If there was a fallthrough into this case, make sure to redirect it to 903421048698b6b6bf86754190bcfe98a0ed82ee5b5Chris Lattner // the end of the switch as well. 904421048698b6b6bf86754190bcfe98a0ed82ee5b5Chris Lattner if (Builder.GetInsertBlock()) { 905421048698b6b6bf86754190bcfe98a0ed82ee5b5Chris Lattner Builder.CreateBr(Block.getBlock()); 906421048698b6b6bf86754190bcfe98a0ed82ee5b5Chris Lattner Builder.ClearInsertionPoint(); 907421048698b6b6bf86754190bcfe98a0ed82ee5b5Chris Lattner } 908b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner return; 909b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner } 910b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner } 911b11f9198111796ada02b57f62cdea92134fde9f7Chris Lattner 912f84dcda7e2ab2f6d5be5a8c52d22ef4c442dd762Daniel Dunbar EmitBlock(createBasicBlock("sw.bb")); 913c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::BasicBlock *CaseDest = Builder.GetInsertBlock(); 91497d5437f48f8d935bf053915ab3d250edfe5fad5Chris Lattner SwitchInsn->addCase(CaseVal, CaseDest); 9151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9165512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // Recursively emitting the statement is acceptable, but is not wonderful for 9175512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // code where we have many case statements nested together, i.e.: 9185512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // case 1: 9195512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // case 2: 9205512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // case 3: etc. 9215512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // Handling this recursively will create a new block for each case statement 9225512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // that falls through to the next case which is IR intensive. It also causes 9235512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // deep recursion which can run into stack depth limitations. Handle 9245512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // sequential non-range case statements specially. 9255512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner const CaseStmt *CurCase = &S; 9265512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner const CaseStmt *NextCase = dyn_cast<CaseStmt>(S.getSubStmt()); 9275512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner 92897d5437f48f8d935bf053915ab3d250edfe5fad5Chris Lattner // Otherwise, iteratively add consecutive cases to this switch stmt. 9295512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner while (NextCase && NextCase->getRHS() == 0) { 9305512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner CurCase = NextCase; 93197d5437f48f8d935bf053915ab3d250edfe5fad5Chris Lattner llvm::ConstantInt *CaseVal = 932a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith Builder.getInt(CurCase->getLHS()->EvaluateKnownConstInt(getContext())); 93397d5437f48f8d935bf053915ab3d250edfe5fad5Chris Lattner SwitchInsn->addCase(CaseVal, CaseDest); 9345512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner NextCase = dyn_cast<CaseStmt>(CurCase->getSubStmt()); 9355512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner } 9361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9375512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner // Normal default recursion for non-cases. 9385512f28fa7b26e87e613dc1558b29b2a89647809Chris Lattner EmitStmt(CurCase->getSubStmt()); 93951b09f2c528c8460b5465c676173324e44176d62Devang Patel} 94051b09f2c528c8460b5465c676173324e44176d62Devang Patel 94151b09f2c528c8460b5465c676173324e44176d62Devang Patelvoid CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) { 94216f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest(); 9431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump assert(DefaultBlock->empty() && 94455e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar "EmitDefaultStmt: Default block already defined?"); 94516f23570999cac1fa13597386938450843003840Daniel Dunbar EmitBlock(DefaultBlock); 94651b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getSubStmt()); 94751b09f2c528c8460b5465c676173324e44176d62Devang Patel} 94851b09f2c528c8460b5465c676173324e44176d62Devang Patel 949fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// CollectStatementsForCase - Given the body of a 'switch' statement and a 950fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// constant value that is being switched on, see if we can dead code eliminate 951fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// the body of the switch to a simple series of statements to emit. Basically, 952fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// on a switch (5) we want to find these statements: 953fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// case 5: 954fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// printf(...); <-- 955fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// ++i; <-- 956fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// break; 957fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// 958fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// and add them to the ResultStmts vector. If it is unsafe to do this 959fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// transformation (for example, one of the elided statements contains a label 960fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// that might be jumped to), return CSFC_Failure. If we handled it and 'S' 961fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// should include statements after it (e.g. the printf() line is a substmt of 962fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// the case) then return CSFC_FallThrough. If we handled it and found a break 963fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// statement, then return CSFC_Success. 964fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// 965fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// If Case is non-null, then we are looking for the specified case, checking 966fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// that nothing we jump over contains labels. If Case is null, then we found 967fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// the case and are looking for the break. 968fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// 969fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// If the recursive walk actually finds our Case, then we set FoundCase to 970fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// true. 971fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// 972fda0f1f5a278548b012401be07e287c1697fc41cChris Lattnerenum CSFC_Result { CSFC_Failure, CSFC_FallThrough, CSFC_Success }; 973fda0f1f5a278548b012401be07e287c1697fc41cChris Lattnerstatic CSFC_Result CollectStatementsForCase(const Stmt *S, 974fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner const SwitchCase *Case, 975fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner bool &FoundCase, 9765f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<const Stmt*> &ResultStmts) { 9773858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // If this is a null statement, just succeed. 9783858938b043bac2f046304ff99a54905acdcc6ddChris Lattner if (S == 0) 9793858938b043bac2f046304ff99a54905acdcc6ddChris Lattner return Case ? CSFC_Success : CSFC_FallThrough; 9803858938b043bac2f046304ff99a54905acdcc6ddChris Lattner 981fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // If this is the switchcase (case 4: or default) that we're looking for, then 982fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // we're in business. Just add the substatement. 983fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner if (const SwitchCase *SC = dyn_cast<SwitchCase>(S)) { 984fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner if (S == Case) { 985fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner FoundCase = true; 986fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner return CollectStatementsForCase(SC->getSubStmt(), 0, FoundCase, 987fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner ResultStmts); 988fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner } 989fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner 990fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // Otherwise, this is some other case or default statement, just ignore it. 991fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner return CollectStatementsForCase(SC->getSubStmt(), Case, FoundCase, 992fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner ResultStmts); 993fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner } 9943858938b043bac2f046304ff99a54905acdcc6ddChris Lattner 9953858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // If we are in the live part of the code and we found our break statement, 9963858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // return a success! 9973858938b043bac2f046304ff99a54905acdcc6ddChris Lattner if (Case == 0 && isa<BreakStmt>(S)) 9983858938b043bac2f046304ff99a54905acdcc6ddChris Lattner return CSFC_Success; 999fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner 10003858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // If this is a switch statement, then it might contain the SwitchCase, the 10013858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // break, or neither. 10023858938b043bac2f046304ff99a54905acdcc6ddChris Lattner if (const CompoundStmt *CS = dyn_cast<CompoundStmt>(S)) { 10033858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // Handle this as two cases: we might be looking for the SwitchCase (if so 10043858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // the skipped statements must be skippable) or we might already have it. 10053858938b043bac2f046304ff99a54905acdcc6ddChris Lattner CompoundStmt::const_body_iterator I = CS->body_begin(), E = CS->body_end(); 10063858938b043bac2f046304ff99a54905acdcc6ddChris Lattner if (Case) { 10073f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner // Keep track of whether we see a skipped declaration. The code could be 10083f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner // using the declaration even if it is skipped, so we can't optimize out 10093f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner // the decl if the kept statements might refer to it. 10103f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner bool HadSkippedDecl = false; 10113f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner 10123858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // If we're looking for the case, just see if we can skip each of the 10133858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // substatements. 10143858938b043bac2f046304ff99a54905acdcc6ddChris Lattner for (; Case && I != E; ++I) { 10154d509341bd5db06a517daa311379f52bb540bc34Eli Friedman HadSkippedDecl |= isa<DeclStmt>(*I); 10163f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner 10173858938b043bac2f046304ff99a54905acdcc6ddChris Lattner switch (CollectStatementsForCase(*I, Case, FoundCase, ResultStmts)) { 10183858938b043bac2f046304ff99a54905acdcc6ddChris Lattner case CSFC_Failure: return CSFC_Failure; 10193858938b043bac2f046304ff99a54905acdcc6ddChris Lattner case CSFC_Success: 10203858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // A successful result means that either 1) that the statement doesn't 10213858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // have the case and is skippable, or 2) does contain the case value 10229467110fcef8a3e4caf9e5d022cff0322afe6e8bChris Lattner // and also contains the break to exit the switch. In the later case, 10239467110fcef8a3e4caf9e5d022cff0322afe6e8bChris Lattner // we just verify the rest of the statements are elidable. 10249467110fcef8a3e4caf9e5d022cff0322afe6e8bChris Lattner if (FoundCase) { 10253f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner // If we found the case and skipped declarations, we can't do the 10263f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner // optimization. 10273f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner if (HadSkippedDecl) 10283f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner return CSFC_Failure; 10293f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner 10309467110fcef8a3e4caf9e5d022cff0322afe6e8bChris Lattner for (++I; I != E; ++I) 10319467110fcef8a3e4caf9e5d022cff0322afe6e8bChris Lattner if (CodeGenFunction::ContainsLabel(*I, true)) 10329467110fcef8a3e4caf9e5d022cff0322afe6e8bChris Lattner return CSFC_Failure; 10339467110fcef8a3e4caf9e5d022cff0322afe6e8bChris Lattner return CSFC_Success; 10349467110fcef8a3e4caf9e5d022cff0322afe6e8bChris Lattner } 10353858938b043bac2f046304ff99a54905acdcc6ddChris Lattner break; 10363858938b043bac2f046304ff99a54905acdcc6ddChris Lattner case CSFC_FallThrough: 10373858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // If we have a fallthrough condition, then we must have found the 10383858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // case started to include statements. Consider the rest of the 10393858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // statements in the compound statement as candidates for inclusion. 10403858938b043bac2f046304ff99a54905acdcc6ddChris Lattner assert(FoundCase && "Didn't find case but returned fallthrough?"); 10413858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // We recursively found Case, so we're not looking for it anymore. 10423858938b043bac2f046304ff99a54905acdcc6ddChris Lattner Case = 0; 10433f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner 10443f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner // If we found the case and skipped declarations, we can't do the 10453f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner // optimization. 10463f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner if (HadSkippedDecl) 10473f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner return CSFC_Failure; 10483858938b043bac2f046304ff99a54905acdcc6ddChris Lattner break; 10493858938b043bac2f046304ff99a54905acdcc6ddChris Lattner } 10503858938b043bac2f046304ff99a54905acdcc6ddChris Lattner } 10513858938b043bac2f046304ff99a54905acdcc6ddChris Lattner } 10523858938b043bac2f046304ff99a54905acdcc6ddChris Lattner 10533858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // If we have statements in our range, then we know that the statements are 10543858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // live and need to be added to the set of statements we're tracking. 10553858938b043bac2f046304ff99a54905acdcc6ddChris Lattner for (; I != E; ++I) { 10563858938b043bac2f046304ff99a54905acdcc6ddChris Lattner switch (CollectStatementsForCase(*I, 0, FoundCase, ResultStmts)) { 10573858938b043bac2f046304ff99a54905acdcc6ddChris Lattner case CSFC_Failure: return CSFC_Failure; 10583858938b043bac2f046304ff99a54905acdcc6ddChris Lattner case CSFC_FallThrough: 10593858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // A fallthrough result means that the statement was simple and just 10603858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // included in ResultStmt, keep adding them afterwards. 10613858938b043bac2f046304ff99a54905acdcc6ddChris Lattner break; 10623858938b043bac2f046304ff99a54905acdcc6ddChris Lattner case CSFC_Success: 10633858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // A successful result means that we found the break statement and 10643858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // stopped statement inclusion. We just ensure that any leftover stmts 10653858938b043bac2f046304ff99a54905acdcc6ddChris Lattner // are skippable and return success ourselves. 10663858938b043bac2f046304ff99a54905acdcc6ddChris Lattner for (++I; I != E; ++I) 10673858938b043bac2f046304ff99a54905acdcc6ddChris Lattner if (CodeGenFunction::ContainsLabel(*I, true)) 10683858938b043bac2f046304ff99a54905acdcc6ddChris Lattner return CSFC_Failure; 10693858938b043bac2f046304ff99a54905acdcc6ddChris Lattner return CSFC_Success; 10703858938b043bac2f046304ff99a54905acdcc6ddChris Lattner } 10713858938b043bac2f046304ff99a54905acdcc6ddChris Lattner } 10723858938b043bac2f046304ff99a54905acdcc6ddChris Lattner 10733858938b043bac2f046304ff99a54905acdcc6ddChris Lattner return Case ? CSFC_Success : CSFC_FallThrough; 10743858938b043bac2f046304ff99a54905acdcc6ddChris Lattner } 10753858938b043bac2f046304ff99a54905acdcc6ddChris Lattner 1076fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // Okay, this is some other statement that we don't handle explicitly, like a 1077fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // for statement or increment etc. If we are skipping over this statement, 1078fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // just verify it doesn't have labels, which would make it invalid to elide. 1079fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner if (Case) { 10803f06e274736eab9821ce0dc2bd8e166fe0e3aa7eChris Lattner if (CodeGenFunction::ContainsLabel(S, true)) 1081fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner return CSFC_Failure; 1082fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner return CSFC_Success; 1083fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner } 1084fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner 1085fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // Otherwise, we want to include this statement. Everything is cool with that 1086fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // so long as it doesn't contain a break out of the switch we're in. 1087fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner if (CodeGenFunction::containsBreak(S)) return CSFC_Failure; 1088fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner 1089fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // Otherwise, everything is great. Include the statement and tell the caller 1090fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // that we fall through and include the next statement as well. 1091fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner ResultStmts.push_back(S); 1092fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner return CSFC_FallThrough; 1093fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner} 1094fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner 1095fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// FindCaseStatementsForValue - Find the case statement being jumped to and 1096fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// then invoke CollectStatementsForCase to find the list of statements to emit 1097fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// for a switch on constant. See the comment above CollectStatementsForCase 1098fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner/// for more details. 1099fda0f1f5a278548b012401be07e287c1697fc41cChris Lattnerstatic bool FindCaseStatementsForValue(const SwitchStmt &S, 1100fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner const llvm::APInt &ConstantCondValue, 11015f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<const Stmt*> &ResultStmts, 1102fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner ASTContext &C) { 1103fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // First step, find the switch case that is being branched to. We can do this 1104fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // efficiently by scanning the SwitchCase list. 1105fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner const SwitchCase *Case = S.getSwitchCaseList(); 1106fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner const DefaultStmt *DefaultCase = 0; 1107fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner 1108fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner for (; Case; Case = Case->getNextSwitchCase()) { 1109fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // It's either a default or case. Just remember the default statement in 1110fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // case we're not jumping to any numbered cases. 1111fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner if (const DefaultStmt *DS = dyn_cast<DefaultStmt>(Case)) { 1112fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner DefaultCase = DS; 1113fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner continue; 1114fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner } 1115fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner 1116fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // Check to see if this case is the one we're looking for. 1117fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner const CaseStmt *CS = cast<CaseStmt>(Case); 1118fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // Don't handle case ranges yet. 1119fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner if (CS->getRHS()) return false; 1120fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner 1121fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // If we found our case, remember it as 'case'. 1122a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith if (CS->getLHS()->EvaluateKnownConstInt(C) == ConstantCondValue) 1123fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner break; 1124fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner } 1125fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner 1126fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // If we didn't find a matching case, we use a default if it exists, or we 1127fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // elide the whole switch body! 1128fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner if (Case == 0) { 1129fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // It is safe to elide the body of the switch if it doesn't contain labels 1130fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // etc. If it is safe, return successfully with an empty ResultStmts list. 1131fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner if (DefaultCase == 0) 1132fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner return !CodeGenFunction::ContainsLabel(&S); 1133fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner Case = DefaultCase; 1134fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner } 1135fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner 1136fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // Ok, we know which case is being jumped to, try to collect all the 1137fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // statements that follow it. This can fail for a variety of reasons. Also, 1138fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // check to see that the recursive walk actually found our case statement. 1139fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // Insane cases like this can fail to find it in the recursive walk since we 1140fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // don't handle every stmt kind: 1141fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // switch (4) { 1142fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // while (1) { 1143fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // case 4: ... 1144fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner bool FoundCase = false; 1145fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner return CollectStatementsForCase(S.getBody(), Case, FoundCase, 1146fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner ResultStmts) != CSFC_Failure && 1147fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner FoundCase; 1148fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner} 1149fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner 115051b09f2c528c8460b5465c676173324e44176d62Devang Patelvoid CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { 1151f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest SwitchExit = getJumpDestInCurrentScope("sw.epilog"); 1152f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1153f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall RunCleanupsScope ConditionScope(*this); 1154d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor 1155d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor if (S.getConditionVariable()) 1156b6bbcc9995186799a60ce17d0c1acff31601653aJohn McCall EmitAutoVarDecl(*S.getConditionVariable()); 1157d3d5301c44138b92bf01286183f5bf310cdd37cfDouglas Gregor 1158985df1c1f2d0666a09bc03f3593929286b0dea65Fariborz Jahanian // Handle nested switch statements. 1159985df1c1f2d0666a09bc03f3593929286b0dea65Fariborz Jahanian llvm::SwitchInst *SavedSwitchInsn = SwitchInsn; 1160985df1c1f2d0666a09bc03f3593929286b0dea65Fariborz Jahanian llvm::BasicBlock *SavedCRBlock = CaseRangeBlock; 1161985df1c1f2d0666a09bc03f3593929286b0dea65Fariborz Jahanian 1162fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // See if we can constant fold the condition of the switch and therefore only 1163fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // emit the live case statement (if any) of the switch. 1164fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner llvm::APInt ConstantCondValue; 1165fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner if (ConstantFoldsToSimpleInteger(S.getCond(), ConstantCondValue)) { 11665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<const Stmt*, 4> CaseStmts; 1167fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner if (FindCaseStatementsForValue(S, ConstantCondValue, CaseStmts, 1168fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner getContext())) { 1169fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner RunCleanupsScope ExecutedScope(*this); 1170fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner 1171985df1c1f2d0666a09bc03f3593929286b0dea65Fariborz Jahanian // At this point, we are no longer "within" a switch instance, so 1172985df1c1f2d0666a09bc03f3593929286b0dea65Fariborz Jahanian // we can temporarily enforce this to ensure that any embedded case 1173985df1c1f2d0666a09bc03f3593929286b0dea65Fariborz Jahanian // statements are not emitted. 1174985df1c1f2d0666a09bc03f3593929286b0dea65Fariborz Jahanian SwitchInsn = 0; 1175985df1c1f2d0666a09bc03f3593929286b0dea65Fariborz Jahanian 1176fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // Okay, we can dead code eliminate everything except this case. Emit the 1177fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner // specified series of statements and we're good. 1178fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner for (unsigned i = 0, e = CaseStmts.size(); i != e; ++i) 1179fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner EmitStmt(CaseStmts[i]); 1180985df1c1f2d0666a09bc03f3593929286b0dea65Fariborz Jahanian 1181985df1c1f2d0666a09bc03f3593929286b0dea65Fariborz Jahanian // Now we want to restore the saved switch instance so that nested switches 1182985df1c1f2d0666a09bc03f3593929286b0dea65Fariborz Jahanian // continue to function properly 1183985df1c1f2d0666a09bc03f3593929286b0dea65Fariborz Jahanian SwitchInsn = SavedSwitchInsn; 1184985df1c1f2d0666a09bc03f3593929286b0dea65Fariborz Jahanian 1185fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner return; 1186fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner } 1187fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner } 1188fda0f1f5a278548b012401be07e287c1697fc41cChris Lattner 118951b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::Value *CondV = EmitScalarExpr(S.getCond()); 119051b09f2c528c8460b5465c676173324e44176d62Devang Patel 119116f23570999cac1fa13597386938450843003840Daniel Dunbar // Create basic block to hold stuff that comes after switch 119216f23570999cac1fa13597386938450843003840Daniel Dunbar // statement. We also need to create a default block now so that 119316f23570999cac1fa13597386938450843003840Daniel Dunbar // explicit case ranges tests can have a place to jump to on 119416f23570999cac1fa13597386938450843003840Daniel Dunbar // failure. 119555e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar llvm::BasicBlock *DefaultBlock = createBasicBlock("sw.default"); 119616f23570999cac1fa13597386938450843003840Daniel Dunbar SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock); 119716f23570999cac1fa13597386938450843003840Daniel Dunbar CaseRangeBlock = DefaultBlock; 119851b09f2c528c8460b5465c676173324e44176d62Devang Patel 11990912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // Clear the insertion point to indicate we are in unreachable code. 12000912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar Builder.ClearInsertionPoint(); 1201d28a80d64616b66c91d28bb4c08ca2d8c594de4eEli Friedman 1202e9b8c0a38549692f1b8f688c05c35442fc620865Devang Patel // All break statements jump to NextBlock. If BreakContinueStack is non empty 1203e9b8c0a38549692f1b8f688c05c35442fc620865Devang Patel // then reuse last ContinueBlock. 1204f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall JumpDest OuterContinue; 1205e4b6d342c29d5cb9d311756100df1603810fa892Anders Carlsson if (!BreakContinueStack.empty()) 1206f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall OuterContinue = BreakContinueStack.back().ContinueBlock; 1207e4b6d342c29d5cb9d311756100df1603810fa892Anders Carlsson 1208f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall BreakContinueStack.push_back(BreakContinue(SwitchExit, OuterContinue)); 120951b09f2c528c8460b5465c676173324e44176d62Devang Patel 121051b09f2c528c8460b5465c676173324e44176d62Devang Patel // Emit switch body. 121151b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getBody()); 12121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1213e4b6d342c29d5cb9d311756100df1603810fa892Anders Carlsson BreakContinueStack.pop_back(); 121451b09f2c528c8460b5465c676173324e44176d62Devang Patel 121516f23570999cac1fa13597386938450843003840Daniel Dunbar // Update the default block in case explicit case range tests have 121616f23570999cac1fa13597386938450843003840Daniel Dunbar // been chained on top. 1217ab14ae2ab16088b6a7f69eac6e152c3e9f9ea01bStepan Dyatkovskiy SwitchInsn->setDefaultDest(CaseRangeBlock); 12181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1219f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If a default was never emitted: 122016f23570999cac1fa13597386938450843003840Daniel Dunbar if (!DefaultBlock->getParent()) { 1221f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // If we have cleanups, emit the default block so that there's a 1222f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // place to jump through the cleanups from. 1223f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall if (ConditionScope.requiresCleanups()) { 1224f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall EmitBlock(DefaultBlock); 1225f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall 1226f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Otherwise, just forward the default block to the switch end. 1227f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } else { 1228ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall DefaultBlock->replaceAllUsesWith(SwitchExit.getBlock()); 1229f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall delete DefaultBlock; 1230f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall } 123116f23570999cac1fa13597386938450843003840Daniel Dunbar } 123216f23570999cac1fa13597386938450843003840Daniel Dunbar 1233ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall ConditionScope.ForceCleanup(); 1234ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall 123516f23570999cac1fa13597386938450843003840Daniel Dunbar // Emit continuation. 1236ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall EmitBlock(SwitchExit.getBlock(), true); 123751b09f2c528c8460b5465c676173324e44176d62Devang Patel 123851b09f2c528c8460b5465c676173324e44176d62Devang Patel SwitchInsn = SavedSwitchInsn; 1239c049e4f406a7f7179eba98659044a32508e53289Devang Patel CaseRangeBlock = SavedCRBlock; 124051b09f2c528c8460b5465c676173324e44176d62Devang Patel} 1241fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 12422819fa85651526d59ade4fdc9da2cadd7b132973Chris Lattnerstatic std::string 1243444be7366d0a1e172c0290a1ea54c1cb16b5947cDaniel DunbarSimplifyConstraint(const char *Constraint, const TargetInfo &Target, 12445f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<TargetInfo::ConstraintInfo> *OutCons=0) { 1245fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Result; 12461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1247fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson while (*Constraint) { 1248fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson switch (*Constraint) { 1249fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson default: 1250002333f8b2cf1a8614e532f6ce366b21af85142cStuart Hastings Result += Target.convertConstraint(Constraint); 1251fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 1252fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Ignore these 1253fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '*': 1254fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '?': 1255fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '!': 1256ef44e1110711276ffffe4b22d4ba0cebd49cb330John Thompson case '=': // Will see this and the following in mult-alt constraints. 1257ef44e1110711276ffffe4b22d4ba0cebd49cb330John Thompson case '+': 1258ef44e1110711276ffffe4b22d4ba0cebd49cb330John Thompson break; 12592f474ea9ef7505df5d092287c48c19974222293bJohn Thompson case ',': 12602f474ea9ef7505df5d092287c48c19974222293bJohn Thompson Result += "|"; 1261fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 1262fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case 'g': 1263fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += "imr"; 1264fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 1265300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson case '[': { 12662819fa85651526d59ade4fdc9da2cadd7b132973Chris Lattner assert(OutCons && 1267300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson "Must pass output names to constraints with a symbolic name"); 1268300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson unsigned Index; 12691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bool result = Target.resolveSymbolicName(Constraint, 12702819fa85651526d59ade4fdc9da2cadd7b132973Chris Lattner &(*OutCons)[0], 12712819fa85651526d59ade4fdc9da2cadd7b132973Chris Lattner OutCons->size(), Index); 1272cbf40f913aa2aa5de6e0540fed209405d00a2c69Chris Lattner assert(result && "Could not resolve symbolic name"); (void)result; 1273300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson Result += llvm::utostr(Index); 1274300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson break; 1275300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson } 1276fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 12771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1278fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraint++; 1279fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 12801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1281fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson return Result; 1282fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 1283fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 128403117d1b2e32d18652401b12d9049871992bf3adRafael Espindola/// AddVariableConstraints - Look at AsmExpr and if it is a variable declared 128503117d1b2e32d18652401b12d9049871992bf3adRafael Espindola/// as using a particular register add that as a constraint that will be used 128603117d1b2e32d18652401b12d9049871992bf3adRafael Espindola/// in this asm stmt. 12870ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindolastatic std::string 128803117d1b2e32d18652401b12d9049871992bf3adRafael EspindolaAddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr, 128903117d1b2e32d18652401b12d9049871992bf3adRafael Espindola const TargetInfo &Target, CodeGenModule &CGM, 129003117d1b2e32d18652401b12d9049871992bf3adRafael Espindola const AsmStmt &Stmt) { 12910ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola const DeclRefExpr *AsmDeclRef = dyn_cast<DeclRefExpr>(&AsmExpr); 12920ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola if (!AsmDeclRef) 12930ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola return Constraint; 12940ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola const ValueDecl &Value = *AsmDeclRef->getDecl(); 12950ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola const VarDecl *Variable = dyn_cast<VarDecl>(&Value); 12960ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola if (!Variable) 12970ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola return Constraint; 12980ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola AsmLabelAttr *Attr = Variable->getAttr<AsmLabelAttr>(); 12990ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola if (!Attr) 13000ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola return Constraint; 13015f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Register = Attr->getLabel(); 1302baf86955a9a390f2643a1ea9806832eb4a92f716Rafael Espindola assert(Target.isValidGCCRegisterName(Register)); 1303e3e07a5b3490bc2977859d56bac211afac2236fbEric Christopher // We're using validateOutputConstraint here because we only care if 1304e3e07a5b3490bc2977859d56bac211afac2236fbEric Christopher // this is a register constraint. 1305e3e07a5b3490bc2977859d56bac211afac2236fbEric Christopher TargetInfo::ConstraintInfo Info(Constraint, ""); 1306e3e07a5b3490bc2977859d56bac211afac2236fbEric Christopher if (Target.validateOutputConstraint(Info) && 1307e3e07a5b3490bc2977859d56bac211afac2236fbEric Christopher !Info.allowsRegister()) { 13080ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola CGM.ErrorUnsupported(&Stmt, "__asm__"); 13090ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola return Constraint; 13100ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola } 131143fec879a527c74ff01d8aa2bf94a12432249fc7Eric Christopher // Canonicalize the register here before returning it. 131243fec879a527c74ff01d8aa2bf94a12432249fc7Eric Christopher Register = Target.getNormalizedGCCRegisterName(Register); 13130ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola return "{" + Register.str() + "}"; 13140ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola} 13150ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola 13166d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedmanllvm::Value* 13176d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli FriedmanCodeGenFunction::EmitAsmInputLValue(const AsmStmt &S, 13186d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman const TargetInfo::ConstraintInfo &Info, 13196d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman LValue InputValue, QualType InputType, 13206d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman std::string &ConstraintStr) { 1321634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson llvm::Value *Arg; 13221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (Info.allowsRegister() || !Info.allowsMemory()) { 13236d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman if (!CodeGenFunction::hasAggregateLLVMType(InputType)) { 1324545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall Arg = EmitLoadOfLValue(InputValue).getScalarVal(); 1325634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson } else { 13262acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *Ty = ConvertType(InputType); 1327ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson uint64_t Size = CGM.getTargetData().getTypeSizeInBits(Ty); 1328ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson if (Size <= 64 && llvm::isPowerOf2_64(Size)) { 1329d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Ty = llvm::IntegerType::get(getLLVMContext(), Size); 1330ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson Ty = llvm::PointerType::getUnqual(Ty); 13311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13326d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman Arg = Builder.CreateLoad(Builder.CreateBitCast(InputValue.getAddress(), 13336d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman Ty)); 1334ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson } else { 13356d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman Arg = InputValue.getAddress(); 1336ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson ConstraintStr += '*'; 1337ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson } 1338634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson } 1339634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson } else { 13406d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman Arg = InputValue.getAddress(); 1341634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson ConstraintStr += '*'; 1342634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson } 13431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1344634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson return Arg; 1345634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson} 1346634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson 13476d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedmanllvm::Value* CodeGenFunction::EmitAsmInput(const AsmStmt &S, 13486d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman const TargetInfo::ConstraintInfo &Info, 13496d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman const Expr *InputExpr, 13506d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman std::string &ConstraintStr) { 13516d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman if (Info.allowsRegister() || !Info.allowsMemory()) 13526d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman if (!CodeGenFunction::hasAggregateLLVMType(InputExpr->getType())) 13536d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman return EmitScalarExpr(InputExpr); 13546d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman 13556d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman InputExpr = InputExpr->IgnoreParenNoopCasts(getContext()); 13566d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman LValue Dest = EmitLValue(InputExpr); 13576d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman return EmitAsmInputLValue(S, Info, Dest, InputExpr->getType(), ConstraintStr); 13586d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman} 13596d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman 136047fc7e93b6af9e6a967231133a2f4bc626eeed26Chris Lattner/// getAsmSrcLocInfo - Return the !srcloc metadata node to attach to an inline 13615d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner/// asm call instruction. The !srcloc MDNode contains a list of constant 13625d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner/// integers which are the source locations of the start of each line in the 13635d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner/// asm. 136447fc7e93b6af9e6a967231133a2f4bc626eeed26Chris Lattnerstatic llvm::MDNode *getAsmSrcLocInfo(const StringLiteral *Str, 136547fc7e93b6af9e6a967231133a2f4bc626eeed26Chris Lattner CodeGenFunction &CGF) { 13665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Value *, 8> Locs; 13675d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner // Add the location of the first line to the MDNode. 13685d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner Locs.push_back(llvm::ConstantInt::get(CGF.Int32Ty, 13695d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner Str->getLocStart().getRawEncoding())); 13705f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrVal = Str->getString(); 13715d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner if (!StrVal.empty()) { 13725d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner const SourceManager &SM = CGF.CGM.getContext().getSourceManager(); 13735d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner const LangOptions &LangOpts = CGF.CGM.getLangOptions(); 13745d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner 13755d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner // Add the location of the start of each subsequent line of the asm to the 13765d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner // MDNode. 13775d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner for (unsigned i = 0, e = StrVal.size()-1; i != e; ++i) { 13785d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner if (StrVal[i] != '\n') continue; 13795d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner SourceLocation LineLoc = Str->getLocationOfByte(i+1, SM, LangOpts, 13805d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner CGF.Target); 13815d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner Locs.push_back(llvm::ConstantInt::get(CGF.Int32Ty, 13825d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner LineLoc.getRawEncoding())); 13835d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner } 13845d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner } 13855d93653247eeedaff5f0712178953b63d71a0b3bChris Lattner 13866f141659cab11109d9931d92d0988f8850778de3Jay Foad return llvm::MDNode::get(CGF.getLLVMContext(), Locs); 138747fc7e93b6af9e6a967231133a2f4bc626eeed26Chris Lattner} 138847fc7e93b6af9e6a967231133a2f4bc626eeed26Chris Lattner 1389fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlssonvoid CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { 1390458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner // Analyze the asm string to decompose it into its pieces. We know that Sema 1391458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner // has already done this, so it is guaranteed to be successful. 13925f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<AsmStmt::AsmStringPiece, 4> Pieces; 1393fb5058ef67c054296c88db18ab1b3717845cb71dChris Lattner unsigned DiagOffs; 1394fb5058ef67c054296c88db18ab1b3717845cb71dChris Lattner S.AnalyzeAsmString(Pieces, getContext(), DiagOffs); 13951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1396458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner // Assemble the pieces into the final asm string. 1397458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner std::string AsmString; 1398458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner for (unsigned i = 0, e = Pieces.size(); i != e; ++i) { 1399458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner if (Pieces[i].isString()) 1400458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner AsmString += Pieces[i].getString(); 1401458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner else if (Pieces[i].getModifier() == '\0') 1402458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner AsmString += '$' + llvm::utostr(Pieces[i].getOperandNo()); 1403458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner else 1404458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner AsmString += "${" + llvm::utostr(Pieces[i].getOperandNo()) + ':' + 1405458cd9c8a79b25b87dcea43c9d97a4c59f194799Chris Lattner Pieces[i].getModifier() + '}'; 1406281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar } 14071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1408481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner // Get all the output and input constraints together. 14095f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos; 14105f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos; 1411481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner 14121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) { 1413481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner TargetInfo::ConstraintInfo Info(S.getOutputConstraint(i), 1414481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner S.getOutputName(i)); 1415b992259f7790d3fb9fc5c2eb7182d7af9d64f9acChris Lattner bool IsValid = Target.validateOutputConstraint(Info); (void)IsValid; 1416b992259f7790d3fb9fc5c2eb7182d7af9d64f9acChris Lattner assert(IsValid && "Failed to parse output constraint"); 1417481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner OutputConstraintInfos.push_back(Info); 14181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 14191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1420481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) { 1421481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner TargetInfo::ConstraintInfo Info(S.getInputConstraint(i), 1422481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner S.getInputName(i)); 1423b992259f7790d3fb9fc5c2eb7182d7af9d64f9acChris Lattner bool IsValid = Target.validateInputConstraint(OutputConstraintInfos.data(), 1424b992259f7790d3fb9fc5c2eb7182d7af9d64f9acChris Lattner S.getNumOutputs(), Info); 1425b992259f7790d3fb9fc5c2eb7182d7af9d64f9acChris Lattner assert(IsValid && "Failed to parse input constraint"); (void)IsValid; 1426481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner InputConstraintInfos.push_back(Info); 1427481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner } 14281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1429fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Constraints; 14301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1431ede9d900809c4fd0298d52f5a63088ecb8302275Chris Lattner std::vector<LValue> ResultRegDests; 1432ede9d900809c4fd0298d52f5a63088ecb8302275Chris Lattner std::vector<QualType> ResultRegQualTys; 1433ef6de3da8572607f786303c07150daa6e140ab19Jay Foad std::vector<llvm::Type *> ResultRegTypes; 1434ef6de3da8572607f786303c07150daa6e140ab19Jay Foad std::vector<llvm::Type *> ResultTruncRegTypes; 14359cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner std::vector<llvm::Type*> ArgTypes; 1436fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::vector<llvm::Value*> Args; 1437f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 1438f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // Keep track of inout constraints. 1439f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::string InOutConstraints; 1440f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::vector<llvm::Value*> InOutArgs; 14419cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner std::vector<llvm::Type*> InOutArgTypes; 144203eb543cf7ebee463b33b5802b83ac92c21770cfAnders Carlsson 14431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) { 1444481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i]; 144503eb543cf7ebee463b33b5802b83ac92c21770cfAnders Carlsson 1446fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Simplify the output constraint. 1447481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner std::string OutputConstraint(S.getOutputConstraint(i)); 1448a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1, Target); 14491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1450810f6d5d6223adaab0ccf0139f40de6484ad1bb5Chris Lattner const Expr *OutExpr = S.getOutputExpr(i); 1451810f6d5d6223adaab0ccf0139f40de6484ad1bb5Chris Lattner OutExpr = OutExpr->IgnoreParenNoopCasts(getContext()); 14521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1453a18f539628a6506bae6af52eacd541cebefff762Eric Christopher OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr, 1454a18f539628a6506bae6af52eacd541cebefff762Eric Christopher Target, CGM, S); 14550ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola 1456810f6d5d6223adaab0ccf0139f40de6484ad1bb5Chris Lattner LValue Dest = EmitLValue(OutExpr); 1457ede9d900809c4fd0298d52f5a63088ecb8302275Chris Lattner if (!Constraints.empty()) 1458bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson Constraints += ','; 1459bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson 1460a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // If this is a register output, then make the inline asm return it 1461a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // by-value. If this is a memory result, return the value by-reference. 1462ede9d900809c4fd0298d52f5a63088ecb8302275Chris Lattner if (!Info.allowsMemory() && !hasAggregateLLVMType(OutExpr->getType())) { 1463a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner Constraints += "=" + OutputConstraint; 1464ede9d900809c4fd0298d52f5a63088ecb8302275Chris Lattner ResultRegQualTys.push_back(OutExpr->getType()); 1465ede9d900809c4fd0298d52f5a63088ecb8302275Chris Lattner ResultRegDests.push_back(Dest); 1466a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner ResultRegTypes.push_back(ConvertTypeForMem(OutExpr->getType())); 1467a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner ResultTruncRegTypes.push_back(ResultRegTypes.back()); 14681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1469a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // If this output is tied to an input, and if the input is larger, then 1470a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // we need to set the actual result type of the inline asm node to be the 1471a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // same as the input type. 1472a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner if (Info.hasMatchingInput()) { 1473ebfc9857de58a326c84629915d9ffe3f36d8cc26Chris Lattner unsigned InputNo; 1474ebfc9857de58a326c84629915d9ffe3f36d8cc26Chris Lattner for (InputNo = 0; InputNo != S.getNumInputs(); ++InputNo) { 1475ebfc9857de58a326c84629915d9ffe3f36d8cc26Chris Lattner TargetInfo::ConstraintInfo &Input = InputConstraintInfos[InputNo]; 1476aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner if (Input.hasTiedOperand() && Input.getTiedOperand() == i) 1477a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner break; 1478ebfc9857de58a326c84629915d9ffe3f36d8cc26Chris Lattner } 1479ebfc9857de58a326c84629915d9ffe3f36d8cc26Chris Lattner assert(InputNo != S.getNumInputs() && "Didn't find matching input!"); 14801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1481a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner QualType InputTy = S.getInputExpr(InputNo)->getType(); 1482aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner QualType OutputType = OutExpr->getType(); 14831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1484a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner uint64_t InputSize = getContext().getTypeSize(InputTy); 1485aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner if (getContext().getTypeSize(OutputType) < InputSize) { 1486aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner // Form the asm to return the value as a larger integer or fp type. 1487aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner ResultRegTypes.back() = ConvertType(InputTy); 1488a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner } 1489a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner } 1490ef6de3da8572607f786303c07150daa6e140ab19Jay Foad if (llvm::Type* AdjTy = 14914b93d660c6326ec79b5e369317d1051cf826c2f3Peter Collingbourne getTargetHooks().adjustInlineAsmType(*this, OutputConstraint, 14924b93d660c6326ec79b5e369317d1051cf826c2f3Peter Collingbourne ResultRegTypes.back())) 1493f6e2c2039f76fa58799f6d155892d54fc95755e1Dale Johannesen ResultRegTypes.back() = AdjTy; 1494fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 1495fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ArgTypes.push_back(Dest.getAddress()->getType()); 1496cad3ab611ebd3bee3ce6395d649640047f904cdeAnders Carlsson Args.push_back(Dest.getAddress()); 1497f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Constraints += "=*"; 1498fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += OutputConstraint; 1499f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 15001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 150144def070435a2b5d67f0534f7a3a85a7389d60f2Chris Lattner if (Info.isReadWrite()) { 1502f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutConstraints += ','; 1503634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson 1504fca9361839ecc53224c764517e62fc0e15166004Anders Carlsson const Expr *InputExpr = S.getOutputExpr(i); 15056d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman llvm::Value *Arg = EmitAsmInputLValue(S, Info, Dest, InputExpr->getType(), 15066d7cfd7ef82e42ff30ee1dafd2883fd94e9f8294Eli Friedman InOutConstraints); 15071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 150844def070435a2b5d67f0534f7a3a85a7389d60f2Chris Lattner if (Info.allowsRegister()) 15099f2505b934745b18d580ade4dac7b8b16952a30cAnders Carlsson InOutConstraints += llvm::utostr(i); 15109f2505b934745b18d580ade4dac7b8b16952a30cAnders Carlsson else 15119f2505b934745b18d580ade4dac7b8b16952a30cAnders Carlsson InOutConstraints += OutputConstraint; 15122763b3af0a527c3a63cb058b90c22db0b7bcf558Anders Carlsson 1513fca9361839ecc53224c764517e62fc0e15166004Anders Carlsson InOutArgTypes.push_back(Arg->getType()); 1514fca9361839ecc53224c764517e62fc0e15166004Anders Carlsson InOutArgs.push_back(Arg); 1515f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 1516fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 15171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1518fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson unsigned NumConstraints = S.getNumOutputs() + S.getNumInputs(); 15191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1520fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) { 1521fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const Expr *InputExpr = S.getInputExpr(i); 1522fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1523481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i]; 1524481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner 1525ede9d900809c4fd0298d52f5a63088ecb8302275Chris Lattner if (!Constraints.empty()) 1526fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 15271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1528fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Simplify the input constraint. 1529481fef9e25128fe87b19e41c48f771ee20c33cbeChris Lattner std::string InputConstraint(S.getInputConstraint(i)); 1530300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson InputConstraint = SimplifyConstraint(InputConstraint.c_str(), Target, 15312819fa85651526d59ade4fdc9da2cadd7b132973Chris Lattner &OutputConstraintInfos); 1532fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 15330ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola InputConstraint = 153403117d1b2e32d18652401b12d9049871992bf3adRafael Espindola AddVariableConstraints(InputConstraint, 15350ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola *InputExpr->IgnoreParenNoopCasts(getContext()), 15360ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola Target, CGM, S); 15370ec89f928ce5b3294c2ed644ec1a42656e1af39dRafael Espindola 1538634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson llvm::Value *Arg = EmitAsmInput(S, Info, InputExpr, Constraints); 15391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15404df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner // If this input argument is tied to a larger output result, extend the 15414df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner // input to be the same size as the output. The LLVM backend wants to see 15424df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner // the input and output of a matching constraint be the same size. Note 15434df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner // that GCC does not define what the top bits are here. We use zext because 15444df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner // that is usually cheaper, but LLVM IR should really get an anyext someday. 15454df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner if (Info.hasTiedOperand()) { 15464df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner unsigned Output = Info.getTiedOperand(); 1547aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner QualType OutputType = S.getOutputExpr(Output)->getType(); 15484df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner QualType InputTy = InputExpr->getType(); 15491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1550aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner if (getContext().getTypeSize(OutputType) > 15514df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner getContext().getTypeSize(InputTy)) { 15524df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner // Use ptrtoint as appropriate so that we can do our extension. 15534df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner if (isa<llvm::PointerType>(Arg->getType())) 155477b89b87c3b9220fea1bc80f6d6598d2003cc8a8Chris Lattner Arg = Builder.CreatePtrToInt(Arg, IntPtrTy); 15552acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *OutputTy = ConvertType(OutputType); 1556aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner if (isa<llvm::IntegerType>(OutputTy)) 1557aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner Arg = Builder.CreateZExt(Arg, OutputTy); 155893f1322684e928a559286ba1c7cb83af077aa658Peter Collingbourne else if (isa<llvm::PointerType>(OutputTy)) 155993f1322684e928a559286ba1c7cb83af077aa658Peter Collingbourne Arg = Builder.CreateZExt(Arg, IntPtrTy); 156093f1322684e928a559286ba1c7cb83af077aa658Peter Collingbourne else { 156193f1322684e928a559286ba1c7cb83af077aa658Peter Collingbourne assert(OutputTy->isFloatingPointTy() && "Unexpected output type"); 1562aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner Arg = Builder.CreateFPExt(Arg, OutputTy); 156393f1322684e928a559286ba1c7cb83af077aa658Peter Collingbourne } 15644df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner } 15654df4ee0ff6f804e9d3dd478712e3b5b20cd3bf2fChris Lattner } 15662acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner if (llvm::Type* AdjTy = 15674b93d660c6326ec79b5e369317d1051cf826c2f3Peter Collingbourne getTargetHooks().adjustInlineAsmType(*this, InputConstraint, 15684b93d660c6326ec79b5e369317d1051cf826c2f3Peter Collingbourne Arg->getType())) 1569f6e2c2039f76fa58799f6d155892d54fc95755e1Dale Johannesen Arg = Builder.CreateBitCast(Arg, AdjTy); 15701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1571fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ArgTypes.push_back(Arg->getType()); 1572fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Args.push_back(Arg); 1573fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += InputConstraint; 1574fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 15751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1576f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // Append the "input" part of inout constraints last. 1577f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { 1578f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson ArgTypes.push_back(InOutArgTypes[i]); 1579f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Args.push_back(InOutArgs[i]); 1580f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 1581f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Constraints += InOutConstraints; 15821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1583fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Clobbers 1584fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) { 15855f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Clobber = S.getClobber(i)->getString(); 1586fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1587de31fd7eeebdc64fb043463e7f515dab8eccac8dEric Christopher if (Clobber != "memory" && Clobber != "cc") 158883c021c6d33aa173cf1a6e3bc61006dabb042703Anders Carlsson Clobber = Target.getNormalizedGCCRegisterName(Clobber); 15891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1590ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson if (i != 0 || NumConstraints != 0) 1591fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 15921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1593ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson Constraints += "~{"; 1594fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += Clobber; 1595ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson Constraints += '}'; 1596fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 15971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1598fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Add machine specific clobbers 1599ccf614c479ac93326a01e7b373b30759eed7807fEli Friedman std::string MachineClobbers = Target.getClobbers(); 1600ccf614c479ac93326a01e7b373b30759eed7807fEli Friedman if (!MachineClobbers.empty()) { 1601fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (!Constraints.empty()) 1602fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 1603ccf614c479ac93326a01e7b373b30759eed7807fEli Friedman Constraints += MachineClobbers; 1604fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 1605bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson 16062acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *ResultType; 1607a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner if (ResultRegTypes.empty()) 16088b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner ResultType = VoidTy; 1609a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner else if (ResultRegTypes.size() == 1) 1610a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner ResultType = ResultRegTypes[0]; 1611bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson else 1612d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall ResultType = llvm::StructType::get(getLLVMContext(), ResultRegTypes); 16131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16142acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = 1615fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::FunctionType::get(ResultType, ArgTypes, false); 16161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::InlineAsm *IA = 16181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::InlineAsm::get(FTy, AsmString, Constraints, 1619fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.isVolatile() || S.getNumOutputs() == 0); 16204c7d9f1507d0f102bd4133bba63348636facd469Jay Foad llvm::CallInst *Result = Builder.CreateCall(IA, Args); 1621bc0822bad87ac4d2dcac8e1b71960301656a2699Anders Carlsson Result->addAttribute(~0, llvm::Attribute::NoUnwind); 16221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1623fc1a9c312d249a2c7458f763f848ba42685c23f8Chris Lattner // Slap the source location of the inline asm into a !srcloc metadata on the 1624fc1a9c312d249a2c7458f763f848ba42685c23f8Chris Lattner // call. 162547fc7e93b6af9e6a967231133a2f4bc626eeed26Chris Lattner Result->setMetadata("srcloc", getAsmSrcLocInfo(S.getAsmString(), *this)); 16261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1627a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // Extract all of the register value results from the asm. 1628a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner std::vector<llvm::Value*> RegResults; 1629a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner if (ResultRegTypes.size() == 1) { 1630a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner RegResults.push_back(Result); 1631bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson } else { 1632a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner for (unsigned i = 0, e = ResultRegTypes.size(); i != e; ++i) { 1633bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson llvm::Value *Tmp = Builder.CreateExtractValue(Result, i, "asmresult"); 1634a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner RegResults.push_back(Tmp); 1635a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner } 1636a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner } 16371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1638a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner for (unsigned i = 0, e = RegResults.size(); i != e; ++i) { 1639a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner llvm::Value *Tmp = RegResults[i]; 16401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1641a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // If the result type of the LLVM IR asm doesn't match the result type of 1642a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner // the expression, do the conversion. 1643a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner if (ResultRegTypes[i] != ResultTruncRegTypes[i]) { 16442acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::Type *TruncTy = ResultTruncRegTypes[i]; 1645aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner 1646aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner // Truncate the integer result to the right size, note that TruncTy can be 1647aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner // a pointer. 1648aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner if (TruncTy->isFloatingPointTy()) 1649aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner Tmp = Builder.CreateFPTrunc(Tmp, TruncTy); 16502dca88fc6d3e606a8131712be1800e3a4b90ca3eDan Gohman else if (TruncTy->isPointerTy() && Tmp->getType()->isIntegerTy()) { 1651aab64d0b7f41ed30b15ba9210ed859424cbc7455Chris Lattner uint64_t ResSize = CGM.getTargetData().getTypeSizeInBits(TruncTy); 1652d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Tmp = Builder.CreateTrunc(Tmp, 1653d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::IntegerType::get(getLLVMContext(), (unsigned)ResSize)); 1654a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner Tmp = Builder.CreateIntToPtr(Tmp, TruncTy); 16552dca88fc6d3e606a8131712be1800e3a4b90ca3eDan Gohman } else if (Tmp->getType()->isPointerTy() && TruncTy->isIntegerTy()) { 16562dca88fc6d3e606a8131712be1800e3a4b90ca3eDan Gohman uint64_t TmpSize =CGM.getTargetData().getTypeSizeInBits(Tmp->getType()); 1657d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall Tmp = Builder.CreatePtrToInt(Tmp, 1658d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::IntegerType::get(getLLVMContext(), (unsigned)TmpSize)); 16592dca88fc6d3e606a8131712be1800e3a4b90ca3eDan Gohman Tmp = Builder.CreateTrunc(Tmp, TruncTy); 16602dca88fc6d3e606a8131712be1800e3a4b90ca3eDan Gohman } else if (TruncTy->isIntegerTy()) { 16612dca88fc6d3e606a8131712be1800e3a4b90ca3eDan Gohman Tmp = Builder.CreateTrunc(Tmp, TruncTy); 1662f6e2c2039f76fa58799f6d155892d54fc95755e1Dale Johannesen } else if (TruncTy->isVectorTy()) { 1663f6e2c2039f76fa58799f6d155892d54fc95755e1Dale Johannesen Tmp = Builder.CreateBitCast(Tmp, TruncTy); 1664a077b5c8631596f8d7a588933a9de5d08e9ba428Chris Lattner } 1665bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson } 16661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1667545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall EmitStoreThroughLValue(RValue::get(Tmp), ResultRegDests[i]); 1668bad3a94d506874355fc15b336c6f0ed360e46a06Anders Carlsson } 1669fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 1670