CGStmt.cpp revision c71c845fe77ee1f891d60232ec320912d88557ee
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- CGStmt.cpp - Emit LLVM Code from Statements ----------------------===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This contains code to emit Stmt nodes as LLVM code. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 14e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta#include "CGDebugInfo.h" 15e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta#include "CodeGenModule.h" 165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "CodeGenFunction.h" 17de7fb8413b13651fd85b7125d08b3c9ac2816d9dDaniel Dunbar#include "clang/AST/StmtVisitor.h" 18fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson#include "clang/Basic/TargetInfo.h" 19fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson#include "llvm/ADT/StringExtras.h" 2017d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson#include "llvm/InlineAsm.h" 2117d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson#include "llvm/Intrinsics.h" 22ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson#include "llvm/Target/TargetData.h" 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace CodeGen; 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Statement Emission 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 300912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarvoid CodeGenFunction::EmitStopPoint(const Stmt *S) { 310912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (CGDebugInfo *DI = CGM.getDebugInfo()) { 320912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar DI->setLocation(S->getLocStart()); 330912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar DI->EmitStopPoint(CurFn, Builder); 340912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar } 350912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar} 360912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitStmt(const Stmt *S) { 385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(S && "Null statement?"); 39a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar 400912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // Check if we can handle this without bothering to generate an 410912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // insert point or debug info. 420912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (EmitSimpleStmt(S)) 430912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar return; 440912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 45a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar // If we happen to be at an unreachable point just create a dummy 46a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar // basic block to hold the code. We could change parts of irgen to 47a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar // simply not generate this code, but this situation is rare and 48a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar // probably not worth the effort. 49a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar // FIXME: Verify previous performance/effort claim. 50a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar EnsureInsertPoint(); 515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 520912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // Generate a stoppoint if we are emitting debug info. 530912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(S); 54e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta 555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (S->getStmtClass()) { 565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: 571e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner // Must be an expression in a stmt context. Emit the value (to get 581e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner // side-effects) and ignore the result. 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (const Expr *E = dyn_cast<Expr>(S)) { 601e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner if (!hasAggregateLLVMType(E->getType())) 611e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner EmitScalarExpr(E); 629b2dc287177394a8f73833e2ad4f7ca8cd6f22bbChris Lattner else if (E->getType()->isAnyComplexType()) 631e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner EmitComplexExpr(E); 641e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner else 651e4d21ea5849637c49fd4222b09c4b5dedff7765Chris Lattner EmitAggExpr(E, 0, false); 665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 67488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar ErrorUnsupported(S, "statement"); 685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer break; 700ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar case Stmt::IndirectGotoStmtClass: 710ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar EmitIndirectGotoStmt(cast<IndirectGotoStmt>(*S)); break; 725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break; 745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break; 755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::DoStmtClass: EmitDoStmt(cast<DoStmt>(*S)); break; 765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::ForStmtClass: EmitForStmt(cast<ForStmt>(*S)); break; 775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break; 795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break; 80a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar 8151b09f2c528c8460b5465c676173324e44176d62Devang Patel case Stmt::SwitchStmtClass: EmitSwitchStmt(cast<SwitchStmt>(*S)); break; 82fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case Stmt::AsmStmtClass: EmitAsmStmt(cast<AsmStmt>(*S)); break; 830a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar 840a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtTryStmtClass: 8564d5d6c5903157c521af496479d06dc26032d718Anders Carlsson EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S)); 8664d5d6c5903157c521af496479d06dc26032d718Anders Carlsson break; 870a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtCatchStmtClass: 88dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson assert(0 && "@catch statements should be handled by EmitObjCAtTryStmt"); 89dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson break; 900a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtFinallyStmtClass: 9164d5d6c5903157c521af496479d06dc26032d718Anders Carlsson assert(0 && "@finally statements should be handled by EmitObjCAtTryStmt"); 920a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 930a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtThrowStmtClass: 9464d5d6c5903157c521af496479d06dc26032d718Anders Carlsson EmitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(*S)); 950a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 960a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar case Stmt::ObjCAtSynchronizedStmtClass: 9710cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattner EmitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(*S)); 980a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 993d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson case Stmt::ObjCForCollectionStmtClass: 1003d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson EmitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(*S)); 1010a04d77bde7e3a661c2b41b60630d125d09ed6efDaniel Dunbar break; 1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1050912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarbool CodeGenFunction::EmitSimpleStmt(const Stmt *S) { 1060912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar switch (S->getStmtClass()) { 1070912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar default: return false; 1080912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::NullStmtClass: break; 1090912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break; 1100912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break; 1110912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break; 1120912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::BreakStmtClass: EmitBreakStmt(cast<BreakStmt>(*S)); break; 1130912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::ContinueStmtClass: EmitContinueStmt(cast<ContinueStmt>(*S)); break; 1140912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::DefaultStmtClass: EmitDefaultStmt(cast<DefaultStmt>(*S)); break; 1150912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar case Stmt::CaseStmtClass: EmitCaseStmt(cast<CaseStmt>(*S)); break; 1160912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar } 1170912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 1180912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar return true; 1190912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar} 1200912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 1213379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true, 1223379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// this captures the expression result of the last sub-statement and returns it 1233379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner/// (for use by the statement expression extension). 1249b65551d0b387a7597fb39356a4d8ef10046445eChris LattnerRValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, 1259b65551d0b387a7597fb39356a4d8ef10046445eChris Lattner llvm::Value *AggLoc, bool isAggVol) { 126c71c845fe77ee1f891d60232ec320912d88557eeAnders Carlsson 1271c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta CGDebugInfo *DI = CGM.getDebugInfo(); 1281c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta if (DI) { 1290912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EnsureInsertPoint(); 13066031a5594bc9a7dc0dc5137c3e7955f835e4639Daniel Dunbar DI->setLocation(S.getLBracLoc()); 1311c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta DI->EmitRegionStart(CurFn, Builder); 1321c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta } 1331c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta 134c71c845fe77ee1f891d60232ec320912d88557eeAnders Carlsson // Keep track of the current cleanup stack depth. 135c71c845fe77ee1f891d60232ec320912d88557eeAnders Carlsson size_t CleanupStackDepth = CleanupEntries.size(); 136c71c845fe77ee1f891d60232ec320912d88557eeAnders Carlsson 13717d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson // Push a null stack save value. 13817d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson StackSaveValues.push_back(0); 13917d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson 1403379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner for (CompoundStmt::const_body_iterator I = S.body_begin(), 1413379320c10001d7e1ee5d7e7142c417f797cfe82Chris Lattner E = S.body_end()-GetLast; I != E; ++I) 1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(*I); 143e8b9f5b8ea60983c4a74cb8b63879616b914b65aSanjiv Gupta 1441c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta if (DI) { 145a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar EnsureInsertPoint(); 14666031a5594bc9a7dc0dc5137c3e7955f835e4639Daniel Dunbar DI->setLocation(S.getRBracLoc()); 1471c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta DI->EmitRegionEnd(CurFn, Builder); 1481c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta } 1491c6a38bcea17801e9a4738753aee845381af2b6cSanjiv Gupta 15017d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson RValue RV; 15117d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson if (!GetLast) 15217d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson RV = RValue::get(0); 15317d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson else { 15417d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson // We have to special case labels here. They are statements, but when put 15517d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson // at the end of a statement expression, they yield the value of their 15617d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson // subexpression. Handle this by walking through all labels we encounter, 15717d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson // emitting them before we evaluate the subexpr. 15817d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson const Stmt *LastStmt = S.body_back(); 15917d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson while (const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) { 16017d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson EmitLabel(*LS); 16117d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson LastStmt = LS->getSubStmt(); 16217d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson } 1639b65551d0b387a7597fb39356a4d8ef10046445eChris Lattner 16417d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson EnsureInsertPoint(); 16517d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson 16617d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson RV = EmitAnyExpr(cast<Expr>(LastStmt), AggLoc); 16791d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner } 168a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar 16917d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson if (llvm::Value *V = StackSaveValues.pop_back_val()) { 17036a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump StackDepth = V; 17117d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson V = Builder.CreateLoad(V, "tmp"); 17217d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson 17317d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stackrestore); 17417d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson Builder.CreateCall(F, V); 17517d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson } 17617d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson 177c71c845fe77ee1f891d60232ec320912d88557eeAnders Carlsson EmitCleanupBlocks(CleanupStackDepth); 178c71c845fe77ee1f891d60232ec320912d88557eeAnders Carlsson 17917d28a3e0b0efaba14534d0e6d6a307283d96b9fAnders Carlsson return RV; 1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 182a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbarvoid CodeGenFunction::EmitBlock(llvm::BasicBlock *BB, bool IsFinished) { 183d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // Fall out of the current block (if necessary). 184d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(BB); 185a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar 186a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar if (IsFinished && BB->use_empty()) { 187a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar delete BB; 188a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar return; 189a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar } 190a0c21a8faa79e88ac432d116eca58f7a7217195dDaniel Dunbar 191d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar CurFn->getBasicBlockList().push_back(BB); 192d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar Builder.SetInsertPoint(BB); 193d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar} 194d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar 19536a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stumpvoid CodeGenFunction::EmitStackUpdate(const LabelStmt &S) { 19636a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump if (StackDepthMap.find(&S) == StackDepthMap.end()) { 19736a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // If we can't find it, just remember the depth now, 19836a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // so we can validate it later. 19936a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // FIXME: We need to save a place to insert the adjustment, 20036a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // if needed, here, sa that later in EmitLabel, we can 20136a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // backpatch the adjustment into that place, instead of 20236a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // saying unsupported. 20336a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump StackDepthMap[&S] = StackDepth; 20436a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump return; 20536a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump } 20636a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump 20736a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // Find applicable stack depth, if any... 20836a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump llvm::Value *V = StackDepthMap[&S]; 20936a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // V can be 0 here, if it is, be sure to start searching from the 21036a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // top of the function, as we want the next save after that point. 21136a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump for (unsigned int i = 0; i < StackSaveValues.size(); ++i) 21236a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump if (StackSaveValues[i] == V) { 21336a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // The actual depth is actually in the next used slot, if any. 21436a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump while (++i < StackSaveValues.size() 21536a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump && (V = StackSaveValues[i]) == 0) ; 21636a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // If there were no other depth changes, we don't need any 21736a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // adjustments. 21836a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump if (V) { 21936a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump V = Builder.CreateLoad(V, "tmp"); 22036a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // and restore it. 22136a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stackrestore); 22236a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump Builder.CreateCall(F, V); 22336a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump } 22436a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump } else 22536a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // FIXME: Move to semq and assert here, codegen isn't the right 22636a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // time to be checking. 22736a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump CGM.ErrorUnsupported(&S, "invalid goto to VLA scope that has finished"); 22836a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump} 22936a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump 230d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbarvoid CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) { 231d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // Emit a branch from the current block to the target one if this 232d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // was a real block. If this was just a fall-through block after a 233d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // terminator, don't emit it. 234d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); 235d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar 236d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar if (!CurBB || CurBB->getTerminator()) { 237d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // If there is no insert point or the previous block is already 238d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar // terminated, don't touch it. 2395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 2405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, create a fall-through branch. 241d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar Builder.CreateBr(Target); 2425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2435e08ad3cc62ab94649959ae227a9a411a729bf49Daniel Dunbar 2445e08ad3cc62ab94649959ae227a9a411a729bf49Daniel Dunbar Builder.ClearInsertionPoint(); 2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 24791d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattnervoid CodeGenFunction::EmitLabel(const LabelStmt &S) { 2485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S); 24936a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump if (StackDepthMap.find(&S) == StackDepthMap.end()) { 25036a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // We need to remember the stack depth so that we can readjust the 25136a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // stack back to the right depth for this label if we want to 25236a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // transfer here from a different depth. 25336a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump StackDepthMap[&S] = StackDepth; 25436a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump } else { 25536a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump if (StackDepthMap[&S] != StackDepth) { 25636a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // FIXME: Sema needs to ckeck for jumps that cross decls with 25736a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // initializations for C++, and all VLAs, not just the first in 25836a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // a block that does a stacksave. 25936a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // FIXME: We need to save a place to insert the adjustment 26036a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // when we do a EmitStackUpdate on a forward jump, and then 26136a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // backpatch the adjustment into that place. 26236a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump CGM.ErrorUnsupported(&S, "forward goto inside scope with VLA"); 26336a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump } 26436a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump } 2655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(NextBB); 26691d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner} 26791d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner 26891d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner 26991d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattnervoid CodeGenFunction::EmitLabelStmt(const LabelStmt &S) { 27091d723da7b68be5245c3ac58aa2a36d04658cfb8Chris Lattner EmitLabel(S); 2715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getSubStmt()); 2725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitGotoStmt(const GotoStmt &S) { 275a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar // FIXME: Implement goto out in @try or @catch blocks. 276a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar if (!ObjCEHStack.empty()) { 277a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar CGM.ErrorUnsupported(&S, "goto inside an Obj-C exception block"); 278a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar return; 279a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar } 280a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar 2810912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // If this code is reachable then emit a stop point (if generating 2820912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // debug info). We have to do this ourselves because we are on the 2830912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // "simple" statement path. 2840912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (HaveInsertPoint()) 2850912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(&S); 28636a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump 28736a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // We need to adjust the stack, if the destination was (will be) at 28836a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump // a different depth. 28936a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump EmitStackUpdate(*S.getLabel()); 29036a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump 291d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(getBasicBlockForLabel(S.getLabel())); 2925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2940ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbarvoid CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) { 295a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar // FIXME: Implement indirect goto in @try or @catch blocks. 296a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar if (!ObjCEHStack.empty()) { 297a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar CGM.ErrorUnsupported(&S, "goto inside an Obj-C exception block"); 298a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar return; 299a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar } 300a4275d194b656867bdcdb725b2a7ba3251a1a638Daniel Dunbar 3010ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // Emit initial switch which will be patched up later by 3020ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // EmitIndirectSwitches(). We need a default dest, so we use the 3030ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar // current BB, but this is overwritten. 3040ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar llvm::Value *V = Builder.CreatePtrToInt(EmitScalarExpr(S.getTarget()), 3050ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar llvm::Type::Int32Ty, 3060ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar "addr"); 3070ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar llvm::SwitchInst *I = Builder.CreateSwitch(V, Builder.GetInsertBlock()); 3080ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar IndirectSwitches.push_back(I); 3090ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar 310a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar // Clear the insertion point to indicate we are in unreachable code. 311a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar Builder.ClearInsertionPoint(); 3120ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar} 3130ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar 31462b72f642207ba2ba433d686df924dc9594e9897Chris Lattnervoid CodeGenFunction::EmitIfStmt(const IfStmt &S) { 3155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.4.1: The first substatement is executed if the expression compares 3165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // unequal to 0. The condition must be a scalar type. 3175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3189bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // If the condition constant folds and can be elided, try to avoid emitting 3199bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // the condition and the dead arm of the if/else. 32031a0984b5cb4af99d2407c0f25bf5af68df681c6Chris Lattner if (int Cond = ConstantFoldsToSimpleInteger(S.getCond())) { 32162b72f642207ba2ba433d686df924dc9594e9897Chris Lattner // Figure out which block (then or else) is executed. 32262b72f642207ba2ba433d686df924dc9594e9897Chris Lattner const Stmt *Executed = S.getThen(), *Skipped = S.getElse(); 3239bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner if (Cond == -1) // Condition false? 32462b72f642207ba2ba433d686df924dc9594e9897Chris Lattner std::swap(Executed, Skipped); 3259bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner 32662b72f642207ba2ba433d686df924dc9594e9897Chris Lattner // If the skipped block has no labels in it, just emit the executed block. 32762b72f642207ba2ba433d686df924dc9594e9897Chris Lattner // This avoids emitting dead code and simplifies the CFG substantially. 3289bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner if (!ContainsLabel(Skipped)) { 32962b72f642207ba2ba433d686df924dc9594e9897Chris Lattner if (Executed) 33062b72f642207ba2ba433d686df924dc9594e9897Chris Lattner EmitStmt(Executed); 33162b72f642207ba2ba433d686df924dc9594e9897Chris Lattner return; 33262b72f642207ba2ba433d686df924dc9594e9897Chris Lattner } 33362b72f642207ba2ba433d686df924dc9594e9897Chris Lattner } 3349bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner 3359bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // Otherwise, the condition did not fold, or we couldn't elide it. Just emit 3369bc47e29dce8f095be7a6d07dbb02a5a7a112949Chris Lattner // the conditional branch. 337781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar llvm::BasicBlock *ThenBlock = createBasicBlock("if.then"); 338781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar llvm::BasicBlock *ContBlock = createBasicBlock("if.end"); 339781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar llvm::BasicBlock *ElseBlock = ContBlock; 3405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getElse()) 341781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar ElseBlock = createBasicBlock("if.else"); 342781d7ca9b2fd626ef34bdc3fe06765eeff7ab2bcDaniel Dunbar EmitBranchOnBoolExpr(S.getCond(), ThenBlock, ElseBlock); 3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the 'then' code. 3455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ThenBlock); 3465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getThen()); 347d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(ContBlock); 3485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the 'else' code if present. 3505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (const Stmt *Else = S.getElse()) { 3515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ElseBlock); 3525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(Else); 353d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(ContBlock); 3545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 3555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the continuation block for code after the if. 357c22d665ede76f70228055d638a087f4bd438292dDaniel Dunbar EmitBlock(ContBlock, true); 3585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitWhileStmt(const WhileStmt &S) { 3615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the header for the loop, insert it, which will create an uncond br to 3625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // it. 3639615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *LoopHeader = createBasicBlock("while.cond"); 3645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(LoopHeader); 36572cac2ccce8058833f56358e3391e28a8ddeeaa4Mike Stump 36672cac2ccce8058833f56358e3391e28a8ddeeaa4Mike Stump // Create an exit block for when the condition fails, create a block for the 36772cac2ccce8058833f56358e3391e28a8ddeeaa4Mike Stump // body of the loop. 36872cac2ccce8058833f56358e3391e28a8ddeeaa4Mike Stump llvm::BasicBlock *ExitBlock = createBasicBlock("while.end"); 36972cac2ccce8058833f56358e3391e28a8ddeeaa4Mike Stump llvm::BasicBlock *LoopBody = createBasicBlock("while.body"); 37072cac2ccce8058833f56358e3391e28a8ddeeaa4Mike Stump 37172cac2ccce8058833f56358e3391e28a8ddeeaa4Mike Stump // Store the blocks to use for break and continue. 37272cac2ccce8058833f56358e3391e28a8ddeeaa4Mike Stump BreakContinuePush(ExitBlock, LoopHeader); 3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 37416b16206741f5139c4ad870632db8f9ea4c6c943Mike Stump // Evaluate the conditional in the while header. C99 6.8.5.1: The 37516b16206741f5139c4ad870632db8f9ea4c6c943Mike Stump // evaluation of the controlling expression takes place before each 37616b16206741f5139c4ad870632db8f9ea4c6c943Mike Stump // execution of the loop body. 3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 3782c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel 3792c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel // while(1) is common, avoid extra exit blocks. Be sure 3805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // to correctly handle break/continue though. 3812c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel bool EmitBoolCondBranch = true; 3822c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) 3832c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (C->isOne()) 3842c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel EmitBoolCondBranch = false; 3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // As long as the condition is true, go to the loop body. 3872c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (EmitBoolCondBranch) 3882c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock); 38931a0984b5cb4af99d2407c0f25bf5af68df681c6Chris Lattner 3905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the loop body. 3915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(LoopBody); 3925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getBody()); 393da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 39436a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump BreakContinuePop(); 3955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Cycle to the condition. 397d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(LoopHeader); 3985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the exit block. 400c22d665ede76f70228055d638a087f4bd438292dDaniel Dunbar EmitBlock(ExitBlock, true); 4012c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel 4022c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel // If LoopHeader is a simple forwarding block then eliminate it. 4032c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel if (!EmitBoolCondBranch 4042c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel && &LoopHeader->front() == LoopHeader->getTerminator()) { 4052c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel LoopHeader->replaceAllUsesWith(LoopBody); 4062c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel LoopHeader->getTerminator()->eraseFromParent(); 4072c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel LoopHeader->eraseFromParent(); 4082c30d8fee8981ca4f20a477456dae1b722b53f1dDevang Patel } 4095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitDoStmt(const DoStmt &S) { 4125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the body for the loop, insert it, which will create an uncond br to 4135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // it. 4149615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *LoopBody = createBasicBlock("do.body"); 4159615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *AfterDo = createBasicBlock("do.end"); 4165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(LoopBody); 417da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 4189615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *DoCond = createBasicBlock("do.cond"); 419da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 420da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 42136a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump BreakContinuePush(AfterDo, DoCond); 4225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the body of the loop into the block. 4245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getBody()); 4255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 42636a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump BreakContinuePop(); 427da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 428da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner EmitBlock(DoCond); 429da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 4305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5.2: "The evaluation of the controlling expression takes place 4315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // after each execution of the loop body." 4325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the conditional in the while header. 4345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5p2/p4: The first substatement is executed if the expression 4355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // compares unequal to 0. The condition must be a scalar type. 4365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); 43705f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 43805f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // "do {} while (0)" is common in macros, avoid extra blocks. Be sure 43905f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // to correctly handle break/continue though. 44005f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel bool EmitBoolCondBranch = true; 44105f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) 44205f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (C->isZero()) 44305f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel EmitBoolCondBranch = false; 44405f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 4455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // As long as the condition is true, iterate the loop. 44605f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (EmitBoolCondBranch) 44705f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo); 4485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the exit block. 450c22d665ede76f70228055d638a087f4bd438292dDaniel Dunbar EmitBlock(AfterDo, true); 45105f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel 45205f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel // If DoCond is a simple forwarding block then eliminate it. 45305f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel if (!EmitBoolCondBranch && &DoCond->front() == DoCond->getTerminator()) { 45405f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel DoCond->replaceAllUsesWith(AfterDo); 45505f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel DoCond->getTerminator()->eraseFromParent(); 45605f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel DoCond->eraseFromParent(); 45705f6e6bb3a3e8e604c64f04f4ba7ef0e7569cf4eDevang Patel } 4585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitForStmt(const ForStmt &S) { 4615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FIXME: What do we do if the increment (f.e.) contains a stmt expression, 4625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // which contains a continue/break? 463da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 4645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Evaluate the first part before the loop. 4655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getInit()) 4665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getInit()); 4675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Start the loop with a block that tests the condition. 4699615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); 4709615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *AfterFor = createBasicBlock("for.end"); 471da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 4725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(CondBlock); 4735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4743e9da66ac7e88d64d30ee777588677320660cf84Mike Stump llvm::Value *saveStackDepth = StackDepth; 4753e9da66ac7e88d64d30ee777588677320660cf84Mike Stump 47620926c6eaad539459925d857f64600cd4cc77e99Mike Stump // Evaluate the condition if present. If not, treat it as a 47720926c6eaad539459925d857f64600cd4cc77e99Mike Stump // non-zero-constant according to 6.8.5.3p2, aka, true. 4785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (S.getCond()) { 47931a0984b5cb4af99d2407c0f25bf5af68df681c6Chris Lattner // As long as the condition is true, iterate the loop. 4809615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar llvm::BasicBlock *ForBody = createBasicBlock("for.body"); 48131a0984b5cb4af99d2407c0f25bf5af68df681c6Chris Lattner 4825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // C99 6.8.5p2/p4: The first substatement is executed if the expression 4835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // compares unequal to 0. The condition must be a scalar type. 48431a0984b5cb4af99d2407c0f25bf5af68df681c6Chris Lattner EmitBranchOnBoolExpr(S.getCond(), ForBody, AfterFor); 4855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitBlock(ForBody); 4875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 4885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Treat it as a non-zero constant. Don't even create a new block for the 4895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // body, just fall into it. 4905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 492da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // If the for loop doesn't have an increment we can just use the 493da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // condition as the continue block. 494da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner llvm::BasicBlock *ContinueBlock; 495da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner if (S.getInc()) 4969615ecb44f549ae9fa2b4db6ff46bc78befbf62cDaniel Dunbar ContinueBlock = createBasicBlock("for.inc"); 497da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner else 498da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner ContinueBlock = CondBlock; 499da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 500da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Store the blocks to use for break and continue. 5013e9da66ac7e88d64d30ee777588677320660cf84Mike Stump // Ensure any vlas created between there and here, are undone 5023e9da66ac7e88d64d30ee777588677320660cf84Mike Stump BreakContinuePush(AfterFor, ContinueBlock, 5033e9da66ac7e88d64d30ee777588677320660cf84Mike Stump saveStackDepth, saveStackDepth); 5043e9da66ac7e88d64d30ee777588677320660cf84Mike Stump 5055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the condition is true, execute the body of the for stmt. 5065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EmitStmt(S.getBody()); 507da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 50836a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump BreakContinuePop(); 509da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 5105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If there is an increment, emit it next. 511ad12b6d643aba6c36f5cec4c9beb4977a12eace4Daniel Dunbar if (S.getInc()) { 512ad12b6d643aba6c36f5cec4c9beb4977a12eace4Daniel Dunbar EmitBlock(ContinueBlock); 513883f6a7cc7dccb1d675e27121a82614d63492a8dChris Lattner EmitStmt(S.getInc()); 514ad12b6d643aba6c36f5cec4c9beb4977a12eace4Daniel Dunbar } 5155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Finally, branch back up to the condition for the next iteration. 517d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(CondBlock); 5185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 519da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner // Emit the fall-through block. 520c22d665ede76f70228055d638a087f4bd438292dDaniel Dunbar EmitBlock(AfterFor, true); 5215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 5225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 52329e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbarvoid CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) { 52429e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar if (RV.isScalar()) { 52529e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar Builder.CreateStore(RV.getScalarVal(), ReturnValue); 52629e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } else if (RV.isAggregate()) { 52729e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar EmitAggregateCopy(ReturnValue, RV.getAggregateAddr(), Ty); 52829e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } else { 52929e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false); 53029e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar } 531d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(ReturnBlock); 53229e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar} 53329e0bccf2bcce22b877f8b2ed173f564c116b97eDaniel Dunbar 5345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand 5355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// if the function returns void, or may be missing one if the function returns 5365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// non-void. Fun stuff :). 5375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { 53820c802bf305ea44eb36b6fc6ef3c16a0bfca9b66Eli Friedman for (unsigned i = 0; i < StackSaveValues.size(); i++) { 5397e63b8527fa0b065802fc6cb8cb6124d7c23c4a2Anders Carlsson if (StackSaveValues[i]) { 5407e63b8527fa0b065802fc6cb8cb6124d7c23c4a2Anders Carlsson CGM.ErrorUnsupported(&S, "return inside scope with VLA"); 5417e63b8527fa0b065802fc6cb8cb6124d7c23c4a2Anders Carlsson return; 5427e63b8527fa0b065802fc6cb8cb6124d7c23c4a2Anders Carlsson } 543eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson } 544eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson 5455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Emit the result value, even if unused, to evalute the side effects. 5465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const Expr *RV = S.getRetValue(); 5475ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar 5485ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // FIXME: Clean this up by using an LValue for ReturnTemp, 5495ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // EmitStoreThroughLValue, and EmitAnyExpr. 5505ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar if (!ReturnValue) { 5515ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // Make sure not to return anything, but evaluate the expression 5525ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // for side effects. 5535ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar if (RV) 554144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman EmitAnyExpr(RV); 5555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else if (RV == 0) { 5565ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar // Do nothing (return value is left uninitialized) 5574b0029d5f8742760981a3bd58004f75454090a61Chris Lattner } else if (!hasAggregateLLVMType(RV->getType())) { 5585ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar Builder.CreateStore(EmitScalarExpr(RV), ReturnValue); 5599b2dc287177394a8f73833e2ad4f7ca8cd6f22bbChris Lattner } else if (RV->getType()->isAnyComplexType()) { 5605ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar EmitComplexExprIntoAddr(RV, ReturnValue, false); 5615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 5625ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar EmitAggExpr(RV, ReturnValue, false); 5635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 564144ac61f9005a0da4327d4e62a4c453923b7bc0cEli Friedman 565898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar if (!ObjCEHStack.empty()) { 566898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar for (ObjCEHStackType::reverse_iterator i = ObjCEHStack.rbegin(), 567898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar e = ObjCEHStack.rend(); i != e; ++i) { 56855e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar llvm::BasicBlock *ReturnPad = createBasicBlock("return.pad"); 569898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar EmitJumpThroughFinally(*i, ReturnPad); 570898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar EmitBlock(ReturnPad); 571898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar } 572898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar } 573898d508d4c9e9d45914952473e39196b20830a9fDaniel Dunbar 574d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(ReturnBlock); 5755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 5765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid CodeGenFunction::EmitDeclStmt(const DeclStmt &S) { 578e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek for (DeclStmt::const_decl_iterator I = S.decl_begin(), E = S.decl_end(); 579e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek I != E; ++I) 580e4ea1f42c97a436df3e0ae8e129e6bc624ee6790Ted Kremenek EmitDecl(**I); 5816fa5f0943a84233b2e1ec9716eae55643225bfd4Chris Lattner} 582da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 5830912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarvoid CodeGenFunction::EmitBreakStmt(const BreakStmt &S) { 584da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!"); 585da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 5860912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // FIXME: Implement break in @try or @catch blocks. 587e21269bcb732afa70386fdd4c95d22bc2ed943b1Anders Carlsson if (ObjCEHStack.size() != BreakContinueStack.back().EHStackSize) { 588eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson CGM.ErrorUnsupported(&S, "break inside an Obj-C exception block"); 5890912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar return; 5900912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar } 5910912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 59220c802bf305ea44eb36b6fc6ef3c16a0bfca9b66Eli Friedman for (unsigned i = 0; i < StackSaveValues.size(); i++) { 59320c802bf305ea44eb36b6fc6ef3c16a0bfca9b66Eli Friedman if (StackSaveValues[i]) { 59420c802bf305ea44eb36b6fc6ef3c16a0bfca9b66Eli Friedman CGM.ErrorUnsupported(&S, "break inside scope with VLA"); 59520c802bf305ea44eb36b6fc6ef3c16a0bfca9b66Eli Friedman return; 59620c802bf305ea44eb36b6fc6ef3c16a0bfca9b66Eli Friedman } 597eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson } 598eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson 5990912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // If this code is reachable then emit a stop point (if generating 6000912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // debug info). We have to do this ourselves because we are on the 6010912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // "simple" statement path. 6020912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (HaveInsertPoint()) 6030912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(&S); 604da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock; 605d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(Block); 606da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner} 607da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 6080912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbarvoid CodeGenFunction::EmitContinueStmt(const ContinueStmt &S) { 609da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 610da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner 6110912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // FIXME: Implement continue in @try or @catch blocks. 612e21269bcb732afa70386fdd4c95d22bc2ed943b1Anders Carlsson if (ObjCEHStack.size() != BreakContinueStack.back().EHStackSize) { 6130912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar CGM.ErrorUnsupported(&S, "continue inside an Obj-C exception block"); 6140912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar return; 6150912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar } 6160912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar 61720c802bf305ea44eb36b6fc6ef3c16a0bfca9b66Eli Friedman for (unsigned i = 0; i < StackSaveValues.size(); i++) { 61820c802bf305ea44eb36b6fc6ef3c16a0bfca9b66Eli Friedman if (StackSaveValues[i]) { 61920c802bf305ea44eb36b6fc6ef3c16a0bfca9b66Eli Friedman CGM.ErrorUnsupported(&S, "continue inside scope with VLA"); 62020c802bf305ea44eb36b6fc6ef3c16a0bfca9b66Eli Friedman return; 62120c802bf305ea44eb36b6fc6ef3c16a0bfca9b66Eli Friedman } 622eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson } 623eb91f0ecb420f481811f8812ac4d39087e8dd754Anders Carlsson 6240912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // If this code is reachable then emit a stop point (if generating 6250912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // debug info). We have to do this ourselves because we are on the 6260912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // "simple" statement path. 6270912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar if (HaveInsertPoint()) 6280912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar EmitStopPoint(&S); 629da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock; 630d57a871339c7c98d58d93108b806f59bdf4e13e2Daniel Dunbar EmitBranch(Block); 631da13870e99fe33934b2122f06528a5063f78ae4cChris Lattner} 63251b09f2c528c8460b5465c676173324e44176d62Devang Patel 633c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// EmitCaseStmtRange - If case statement range is not too big then 634c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// add multiple cases to switch instruction, one for each value within 635c049e4f406a7f7179eba98659044a32508e53289Devang Patel/// the range. If range is too big then emit "if" condition check. 636c049e4f406a7f7179eba98659044a32508e53289Devang Patelvoid CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) { 6374efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar assert(S.getRHS() && "Expected RHS value in CaseStmt"); 638c049e4f406a7f7179eba98659044a32508e53289Devang Patel 63951fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson llvm::APSInt LHS = S.getLHS()->EvaluateAsInt(getContext()); 64051fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson llvm::APSInt RHS = S.getRHS()->EvaluateAsInt(getContext()); 6414efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar 64216f23570999cac1fa13597386938450843003840Daniel Dunbar // Emit the code for this case. We do this first to make sure it is 64316f23570999cac1fa13597386938450843003840Daniel Dunbar // properly chained from our predecessor before generating the 64416f23570999cac1fa13597386938450843003840Daniel Dunbar // switch machinery to enter this block. 645f84dcda7e2ab2f6d5be5a8c52d22ef4c442dd762Daniel Dunbar EmitBlock(createBasicBlock("sw.bb")); 64616f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *CaseDest = Builder.GetInsertBlock(); 64716f23570999cac1fa13597386938450843003840Daniel Dunbar EmitStmt(S.getSubStmt()); 64816f23570999cac1fa13597386938450843003840Daniel Dunbar 6494efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar // If range is empty, do nothing. 6504efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar if (LHS.isSigned() ? RHS.slt(LHS) : RHS.ult(LHS)) 6514efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar return; 652c049e4f406a7f7179eba98659044a32508e53289Devang Patel 653c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::APInt Range = RHS - LHS; 65416f23570999cac1fa13597386938450843003840Daniel Dunbar // FIXME: parameters such as this should not be hardcoded. 655c049e4f406a7f7179eba98659044a32508e53289Devang Patel if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) { 656c049e4f406a7f7179eba98659044a32508e53289Devang Patel // Range is small enough to add multiple switch instruction cases. 6574efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar for (unsigned i = 0, e = Range.getZExtValue() + 1; i != e; ++i) { 6582d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel SwitchInsn->addCase(llvm::ConstantInt::get(LHS), CaseDest); 6592d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel LHS++; 6602d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel } 661c049e4f406a7f7179eba98659044a32508e53289Devang Patel return; 662c049e4f406a7f7179eba98659044a32508e53289Devang Patel } 663c049e4f406a7f7179eba98659044a32508e53289Devang Patel 66416f23570999cac1fa13597386938450843003840Daniel Dunbar // The range is too big. Emit "if" condition into a new block, 66516f23570999cac1fa13597386938450843003840Daniel Dunbar // making sure to save and restore the current insertion point. 66616f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *RestoreBB = Builder.GetInsertBlock(); 66716f23570999cac1fa13597386938450843003840Daniel Dunbar 66816f23570999cac1fa13597386938450843003840Daniel Dunbar // Push this test onto the chain of range checks (which terminates 66916f23570999cac1fa13597386938450843003840Daniel Dunbar // in the default basic block). The switch's default will be changed 67016f23570999cac1fa13597386938450843003840Daniel Dunbar // to the top of this chain after switch emission is complete. 67116f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *FalseDest = CaseRangeBlock; 67255e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar CaseRangeBlock = createBasicBlock("sw.caserange"); 67316f23570999cac1fa13597386938450843003840Daniel Dunbar 67416f23570999cac1fa13597386938450843003840Daniel Dunbar CurFn->getBasicBlockList().push_back(CaseRangeBlock); 67516f23570999cac1fa13597386938450843003840Daniel Dunbar Builder.SetInsertPoint(CaseRangeBlock); 676c049e4f406a7f7179eba98659044a32508e53289Devang Patel 677c049e4f406a7f7179eba98659044a32508e53289Devang Patel // Emit range check. 678c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::Value *Diff = 6794efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar Builder.CreateSub(SwitchInsn->getCondition(), llvm::ConstantInt::get(LHS), 6804efde8d2c10b091bc9588de18c2c71dca2979e49Daniel Dunbar "tmp"); 681c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::Value *Cond = 682c049e4f406a7f7179eba98659044a32508e53289Devang Patel Builder.CreateICmpULE(Diff, llvm::ConstantInt::get(Range), "tmp"); 683c049e4f406a7f7179eba98659044a32508e53289Devang Patel Builder.CreateCondBr(Cond, CaseDest, FalseDest); 684c049e4f406a7f7179eba98659044a32508e53289Devang Patel 68516f23570999cac1fa13597386938450843003840Daniel Dunbar // Restore the appropriate insertion point. 686a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar if (RestoreBB) 687a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar Builder.SetInsertPoint(RestoreBB); 688a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar else 689a448fb2da03ece39978784793eea68760e8205a1Daniel Dunbar Builder.ClearInsertionPoint(); 690c049e4f406a7f7179eba98659044a32508e53289Devang Patel} 6912d79d0f3ac0ea77b7bdfc3dd11de8cc3ccd91b8cDevang Patel 692c049e4f406a7f7179eba98659044a32508e53289Devang Patelvoid CodeGenFunction::EmitCaseStmt(const CaseStmt &S) { 693c049e4f406a7f7179eba98659044a32508e53289Devang Patel if (S.getRHS()) { 694c049e4f406a7f7179eba98659044a32508e53289Devang Patel EmitCaseStmtRange(S); 695c049e4f406a7f7179eba98659044a32508e53289Devang Patel return; 696c049e4f406a7f7179eba98659044a32508e53289Devang Patel } 697c049e4f406a7f7179eba98659044a32508e53289Devang Patel 698f84dcda7e2ab2f6d5be5a8c52d22ef4c442dd762Daniel Dunbar EmitBlock(createBasicBlock("sw.bb")); 699c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::BasicBlock *CaseDest = Builder.GetInsertBlock(); 70051fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson llvm::APSInt CaseVal = S.getLHS()->EvaluateAsInt(getContext()); 70155e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar SwitchInsn->addCase(llvm::ConstantInt::get(CaseVal), CaseDest); 70251b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getSubStmt()); 70351b09f2c528c8460b5465c676173324e44176d62Devang Patel} 70451b09f2c528c8460b5465c676173324e44176d62Devang Patel 70551b09f2c528c8460b5465c676173324e44176d62Devang Patelvoid CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) { 70616f23570999cac1fa13597386938450843003840Daniel Dunbar llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest(); 70755e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar assert(DefaultBlock->empty() && 70855e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar "EmitDefaultStmt: Default block already defined?"); 70916f23570999cac1fa13597386938450843003840Daniel Dunbar EmitBlock(DefaultBlock); 71051b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getSubStmt()); 71151b09f2c528c8460b5465c676173324e44176d62Devang Patel} 71251b09f2c528c8460b5465c676173324e44176d62Devang Patel 71351b09f2c528c8460b5465c676173324e44176d62Devang Patelvoid CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { 71451b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::Value *CondV = EmitScalarExpr(S.getCond()); 71551b09f2c528c8460b5465c676173324e44176d62Devang Patel 71651b09f2c528c8460b5465c676173324e44176d62Devang Patel // Handle nested switch statements. 71751b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::SwitchInst *SavedSwitchInsn = SwitchInsn; 718c049e4f406a7f7179eba98659044a32508e53289Devang Patel llvm::BasicBlock *SavedCRBlock = CaseRangeBlock; 71951b09f2c528c8460b5465c676173324e44176d62Devang Patel 7203e9da66ac7e88d64d30ee777588677320660cf84Mike Stump // Ensure any vlas created inside are destroyed on break. 7213e9da66ac7e88d64d30ee777588677320660cf84Mike Stump llvm::Value *saveBreakStackDepth = StackDepth; 7223e9da66ac7e88d64d30ee777588677320660cf84Mike Stump 72316f23570999cac1fa13597386938450843003840Daniel Dunbar // Create basic block to hold stuff that comes after switch 72416f23570999cac1fa13597386938450843003840Daniel Dunbar // statement. We also need to create a default block now so that 72516f23570999cac1fa13597386938450843003840Daniel Dunbar // explicit case ranges tests can have a place to jump to on 72616f23570999cac1fa13597386938450843003840Daniel Dunbar // failure. 72755e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar llvm::BasicBlock *NextBlock = createBasicBlock("sw.epilog"); 72855e874299f2ad827646a4ca9ea38c402aaeb38c9Daniel Dunbar llvm::BasicBlock *DefaultBlock = createBasicBlock("sw.default"); 72916f23570999cac1fa13597386938450843003840Daniel Dunbar SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock); 73016f23570999cac1fa13597386938450843003840Daniel Dunbar CaseRangeBlock = DefaultBlock; 73151b09f2c528c8460b5465c676173324e44176d62Devang Patel 7320912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar // Clear the insertion point to indicate we are in unreachable code. 7330912425f79418a215c2fbd2d8fc9511244a4aa46Daniel Dunbar Builder.ClearInsertionPoint(); 734d28a80d64616b66c91d28bb4c08ca2d8c594de4eEli Friedman 735e9b8c0a38549692f1b8f688c05c35442fc620865Devang Patel // All break statements jump to NextBlock. If BreakContinueStack is non empty 736e9b8c0a38549692f1b8f688c05c35442fc620865Devang Patel // then reuse last ContinueBlock. 73751b09f2c528c8460b5465c676173324e44176d62Devang Patel llvm::BasicBlock *ContinueBlock = NULL; 7383e9da66ac7e88d64d30ee777588677320660cf84Mike Stump llvm::Value *saveContinueStackDepth = NULL; 7393e9da66ac7e88d64d30ee777588677320660cf84Mike Stump if (!BreakContinueStack.empty()) { 74051b09f2c528c8460b5465c676173324e44176d62Devang Patel ContinueBlock = BreakContinueStack.back().ContinueBlock; 7413e9da66ac7e88d64d30ee777588677320660cf84Mike Stump saveContinueStackDepth = BreakContinueStack.back().SaveContinueStackDepth; 7423e9da66ac7e88d64d30ee777588677320660cf84Mike Stump } 7433e9da66ac7e88d64d30ee777588677320660cf84Mike Stump // Ensure any vlas created between there and here, are undone 7443e9da66ac7e88d64d30ee777588677320660cf84Mike Stump BreakContinuePush(NextBlock, ContinueBlock, 7453e9da66ac7e88d64d30ee777588677320660cf84Mike Stump saveBreakStackDepth, saveContinueStackDepth); 74651b09f2c528c8460b5465c676173324e44176d62Devang Patel 74751b09f2c528c8460b5465c676173324e44176d62Devang Patel // Emit switch body. 74851b09f2c528c8460b5465c676173324e44176d62Devang Patel EmitStmt(S.getBody()); 74936a2ada69fdb457b0e46d0ef452c150b360d8888Mike Stump BreakContinuePop(); 75051b09f2c528c8460b5465c676173324e44176d62Devang Patel 75116f23570999cac1fa13597386938450843003840Daniel Dunbar // Update the default block in case explicit case range tests have 75216f23570999cac1fa13597386938450843003840Daniel Dunbar // been chained on top. 75316f23570999cac1fa13597386938450843003840Daniel Dunbar SwitchInsn->setSuccessor(0, CaseRangeBlock); 754c049e4f406a7f7179eba98659044a32508e53289Devang Patel 75516f23570999cac1fa13597386938450843003840Daniel Dunbar // If a default was never emitted then reroute any jumps to it and 75616f23570999cac1fa13597386938450843003840Daniel Dunbar // discard. 75716f23570999cac1fa13597386938450843003840Daniel Dunbar if (!DefaultBlock->getParent()) { 75816f23570999cac1fa13597386938450843003840Daniel Dunbar DefaultBlock->replaceAllUsesWith(NextBlock); 75916f23570999cac1fa13597386938450843003840Daniel Dunbar delete DefaultBlock; 76016f23570999cac1fa13597386938450843003840Daniel Dunbar } 76116f23570999cac1fa13597386938450843003840Daniel Dunbar 76216f23570999cac1fa13597386938450843003840Daniel Dunbar // Emit continuation. 763c22d665ede76f70228055d638a087f4bd438292dDaniel Dunbar EmitBlock(NextBlock, true); 76451b09f2c528c8460b5465c676173324e44176d62Devang Patel 76551b09f2c528c8460b5465c676173324e44176d62Devang Patel SwitchInsn = SavedSwitchInsn; 766c049e4f406a7f7179eba98659044a32508e53289Devang Patel CaseRangeBlock = SavedCRBlock; 76751b09f2c528c8460b5465c676173324e44176d62Devang Patel} 768fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 769ce179ab4358c152164899c032302d8b0e81982b6Anders Carlssonstatic std::string ConvertAsmString(const AsmStmt& S, bool &Failed) 770ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson{ 771ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson // FIXME: No need to create new std::string here, we could just make sure 772ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson // that we don't read past the end of the string data. 773ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson std::string str(S.getAsmString()->getStrData(), 774ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson S.getAsmString()->getByteLength()); 775ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson const char *Start = str.c_str(); 776ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 777ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson unsigned NumOperands = S.getNumOutputs() + S.getNumInputs(); 778ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson bool IsSimple = S.isSimple(); 779281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar Failed = false; 780281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar 781fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson static unsigned AsmCounter = 0; 782fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson AsmCounter++; 783fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Result; 7842abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson if (IsSimple) { 7852abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson while (*Start) { 7862abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson switch (*Start) { 7872abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson default: 7882abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Result += *Start; 7892abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson break; 7902abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson case '$': 7912abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Result += "$$"; 7922abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson break; 7932abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 7942abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Start++; 7952abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 7962abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson 7972abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson return Result; 7982abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 799fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 800fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson while (*Start) { 801fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson switch (*Start) { 802fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson default: 803fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += *Start; 804fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 805fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '$': 806fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += "$$"; 807fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 808fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '%': 809fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Escaped character 810fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Start++; 811fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (!*Start) { 812fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // FIXME: This should be caught during Sema. 813fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(0 && "Trailing '%' in asm string."); 814fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 815fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 816fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson char EscapedChar = *Start; 817fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (EscapedChar == '%') { 818fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Escaped percentage sign. 819fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += '%'; 820345f7209692b116ca433a3196c1e3c998e0ffcdeChris Lattner } else if (EscapedChar == '=') { 821fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Generate an unique ID. 822fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += llvm::utostr(AsmCounter); 823fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else if (isdigit(EscapedChar)) { 824fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // %n - Assembler operand n 825fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson char *End; 826fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson unsigned long n = strtoul(Start, &End, 10); 827fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (Start == End) { 828fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // FIXME: This should be caught during Sema. 829fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(0 && "Missing operand!"); 830fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else if (n >= NumOperands) { 831fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // FIXME: This should be caught during Sema. 832fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson assert(0 && "Operand number out of range!"); 833fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 834fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 835fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += '$' + llvm::utostr(n); 8367695f70bbd3e4d42adaa1ef2ff5e1b9ab3d9c345Lauro Ramos Venancio Start = End - 1; 8372abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } else if (isalpha(EscapedChar)) { 8382abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson char *End; 8392abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson 8402abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson unsigned long n = strtoul(Start + 1, &End, 10); 8412abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson if (Start == End) { 8422abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson // FIXME: This should be caught during Sema. 8432abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson assert(0 && "Missing operand!"); 8442abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } else if (n >= NumOperands) { 8452abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson // FIXME: This should be caught during Sema. 8462abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson assert(0 && "Operand number out of range!"); 8472abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson } 8482abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson 8492abd25f29658880f53baf557d51cd1246484ab50Anders Carlsson Result += "${" + llvm::utostr(n) + ':' + EscapedChar + '}'; 8507695f70bbd3e4d42adaa1ef2ff5e1b9ab3d9c345Lauro Ramos Venancio Start = End - 1; 851ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } else if (EscapedChar == '[') { 852ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson std::string SymbolicName; 853ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 854ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson Start++; 855ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 856ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson while (*Start && *Start != ']') { 857ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson SymbolicName += *Start; 858ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 859ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson Start++; 860ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } 861ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 862ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson if (!Start) { 863ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson // FIXME: Should be caught by sema. 864ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson assert(0 && "Could not parse symbolic name"); 865ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } 866ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 867ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson assert(*Start == ']' && "Error parsing symbolic name"); 868ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 869ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson int Index = -1; 870ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 871ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson // Check if this is an output operand. 872ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson for (unsigned i = 0; i < S.getNumOutputs(); i++) { 873ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson if (S.getOutputName(i) == SymbolicName) { 874ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson Index = i; 875ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson break; 876ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } 877ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } 878ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 879ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson if (Index == -1) { 880ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson for (unsigned i = 0; i < S.getNumInputs(); i++) { 881ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson if (S.getInputName(i) == SymbolicName) { 882ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson Index = S.getNumOutputs() + i; 883ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } 884ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } 885ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson } 886ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 887ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson assert(Index != -1 && "Did not find right operand!"); 888ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 889ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson Result += '$' + llvm::utostr(Index); 890ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson 891fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 892281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar Failed = true; 893281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar return ""; 894fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 895fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 896fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Start++; 897fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 898fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 899fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson return Result; 900fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 901fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 902a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venanciostatic std::string SimplifyConstraint(const char* Constraint, 903300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson TargetInfo &Target, 904300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson const std::string *OutputNamesBegin = 0, 905300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson const std::string *OutputNamesEnd = 0) 906300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson{ 907fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Result; 908fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 909fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson while (*Constraint) { 910fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson switch (*Constraint) { 911fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson default: 912a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio Result += Target.convertConstraint(*Constraint); 913fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 914fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Ignore these 915fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '*': 916fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '?': 917fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case '!': 918fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 919fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson case 'g': 920fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Result += "imr"; 921fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson break; 922300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson case '[': { 923300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson assert(OutputNamesBegin && OutputNamesEnd && 924300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson "Must pass output names to constraints with a symbolic name"); 925300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson unsigned Index; 926300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson bool result = Target.resolveSymbolicName(Constraint, 927300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson OutputNamesBegin, 928300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson OutputNamesEnd, Index); 92953637654287a2658fa0c9f67b305795743720936Chris Lattner assert(result && "Could not resolve symbolic name"); result=result; 930300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson Result += llvm::utostr(Index); 931300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson break; 932300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson } 933fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 934fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 935fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraint++; 936fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 937fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 938fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson return Result; 939fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 940fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 941634717238844cf3f51039411be1b27fe1fac622eAnders Carlssonllvm::Value* CodeGenFunction::EmitAsmInput(const AsmStmt &S, 942634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson TargetInfo::ConstraintInfo Info, 943634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson const Expr *InputExpr, 944634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson std::string &ConstraintStr) 945634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson{ 946634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson llvm::Value *Arg; 947634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson if ((Info & TargetInfo::CI_AllowsRegister) || 948ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson !(Info & TargetInfo::CI_AllowsMemory)) { 949ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson const llvm::Type *Ty = ConvertType(InputExpr->getType()); 950ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson 951ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson if (Ty->isSingleValueType()) { 952634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson Arg = EmitScalarExpr(InputExpr); 953634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson } else { 954ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson LValue Dest = EmitLValue(InputExpr); 955ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson 956ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson uint64_t Size = CGM.getTargetData().getTypeSizeInBits(Ty); 957ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson if (Size <= 64 && llvm::isPowerOf2_64(Size)) { 958ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson Ty = llvm::IntegerType::get(Size); 959ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson Ty = llvm::PointerType::getUnqual(Ty); 960ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson 961ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson Arg = Builder.CreateLoad(Builder.CreateBitCast(Dest.getAddress(), Ty)); 962ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson } else { 963ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson Arg = Dest.getAddress(); 964ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson ConstraintStr += '*'; 965ebaae2a3103b443d50444d335ab5ab0ff7680da2Anders Carlsson } 966634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson } 967634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson } else { 968634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson LValue Dest = EmitLValue(InputExpr); 969634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson Arg = Dest.getAddress(); 970634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson ConstraintStr += '*'; 971634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson } 972634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson 973634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson return Arg; 974634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson} 975634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson 976fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlssonvoid CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { 977281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar bool Failed; 978fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string AsmString = 979ce179ab4358c152164899c032302d8b0e81982b6Anders Carlsson ConvertAsmString(S, Failed); 980281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar 981281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar if (Failed) { 982281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar ErrorUnsupported(&S, "asm string"); 983281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar return; 984281f55c8c6aed79f1ac1c6ee848bd94ebd7f936fDaniel Dunbar } 985fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 986fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Constraints; 987fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 988fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::Value *ResultAddr = 0; 989fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const llvm::Type *ResultType = llvm::Type::VoidTy; 990fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 991fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::vector<const llvm::Type*> ArgTypes; 992fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::vector<llvm::Value*> Args; 993f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 994f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // Keep track of inout constraints. 995f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::string InOutConstraints; 996f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::vector<llvm::Value*> InOutArgs; 997f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson std::vector<const llvm::Type*> InOutArgTypes; 99803eb543cf7ebee463b33b5802b83ac92c21770cfAnders Carlsson 99903eb543cf7ebee463b33b5802b83ac92c21770cfAnders Carlsson llvm::SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos; 100003eb543cf7ebee463b33b5802b83ac92c21770cfAnders Carlsson 1001fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) { 1002fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string OutputConstraint(S.getOutputConstraint(i)->getStrData(), 1003fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.getOutputConstraint(i)->getByteLength()); 1004fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1005fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson TargetInfo::ConstraintInfo Info; 1006fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson bool result = Target.validateOutputConstraint(OutputConstraint.c_str(), 1007fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Info); 10083304e55f613ce34d9a14c3aaf06f5949408b3092Chris Lattner assert(result && "Failed to parse output constraint"); result=result; 1009fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 101003eb543cf7ebee463b33b5802b83ac92c21770cfAnders Carlsson OutputConstraintInfos.push_back(Info); 101103eb543cf7ebee463b33b5802b83ac92c21770cfAnders Carlsson 1012fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Simplify the output constraint. 1013a5694b8b0096215137bf1c273764ec93ac4898fdLauro Ramos Venancio OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1, Target); 1014fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1015fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson LValue Dest = EmitLValue(S.getOutputExpr(i)); 1016fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const llvm::Type *DestValueType = 1017fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson cast<llvm::PointerType>(Dest.getAddress()->getType())->getElementType(); 1018fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1019fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // If the first output operand is not a memory dest, we'll 1020fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // make it the return value. 1021fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (i == 0 && !(Info & TargetInfo::CI_AllowsMemory) && 1022d79a726dc3c8af61b486948c97a183c7fe5b0179Dan Gohman DestValueType->isSingleValueType()) { 1023fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ResultAddr = Dest.getAddress(); 1024fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ResultType = DestValueType; 1025fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += "=" + OutputConstraint; 1026fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } else { 1027fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ArgTypes.push_back(Dest.getAddress()->getType()); 1028cad3ab611ebd3bee3ce6395d649640047f904cdeAnders Carlsson Args.push_back(Dest.getAddress()); 1029fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (i != 0) 1030fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 1031f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Constraints += "=*"; 1032fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += OutputConstraint; 1033f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 1034f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 1035f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson if (Info & TargetInfo::CI_ReadWrite) { 1036f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutConstraints += ','; 1037634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson 1038f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson const Expr *InputExpr = S.getOutputExpr(i); 1039634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson llvm::Value *Arg = EmitAsmInput(S, Info, InputExpr, InOutConstraints); 1040f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 10419f2505b934745b18d580ade4dac7b8b16952a30cAnders Carlsson if (Info & TargetInfo::CI_AllowsRegister) 10429f2505b934745b18d580ade4dac7b8b16952a30cAnders Carlsson InOutConstraints += llvm::utostr(i); 10439f2505b934745b18d580ade4dac7b8b16952a30cAnders Carlsson else 10449f2505b934745b18d580ade4dac7b8b16952a30cAnders Carlsson InOutConstraints += OutputConstraint; 10452763b3af0a527c3a63cb058b90c22db0b7bcf558Anders Carlsson 1046f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutArgTypes.push_back(Arg->getType()); 1047f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson InOutArgs.push_back(Arg); 1048f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 1049fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 1050fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1051fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson unsigned NumConstraints = S.getNumOutputs() + S.getNumInputs(); 1052fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1053fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) { 1054fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const Expr *InputExpr = S.getInputExpr(i); 1055fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1056fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string InputConstraint(S.getInputConstraint(i)->getStrData(), 1057fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.getInputConstraint(i)->getByteLength()); 1058fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1059fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson TargetInfo::ConstraintInfo Info; 1060fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson bool result = Target.validateInputConstraint(InputConstraint.c_str(), 106145b050e72d058131e6f169fe54888bb91a003fb5Anders Carlsson S.begin_output_names(), 106245b050e72d058131e6f169fe54888bb91a003fb5Anders Carlsson S.end_output_names(), 106303eb543cf7ebee463b33b5802b83ac92c21770cfAnders Carlsson &OutputConstraintInfos[0], 106453637654287a2658fa0c9f67b305795743720936Chris Lattner Info); result=result; 106542e1ee0702d8267d632df0fdb5c479a582877c6fAnders Carlsson assert(result && "Failed to parse input constraint"); 1066fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1067fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (i != 0 || S.getNumOutputs() > 0) 1068fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 1069fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1070fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Simplify the input constraint. 1071300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson InputConstraint = SimplifyConstraint(InputConstraint.c_str(), Target, 1072300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson S.begin_output_names(), 1073300fb5d0ef7edc87f3fdba17fc8b1184013b35aeAnders Carlsson S.end_output_names()); 1074fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1075634717238844cf3f51039411be1b27fe1fac622eAnders Carlsson llvm::Value *Arg = EmitAsmInput(S, Info, InputExpr, Constraints); 1076fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1077fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson ArgTypes.push_back(Arg->getType()); 1078fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Args.push_back(Arg); 1079fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += InputConstraint; 1080fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 1081fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1082f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson // Append the "input" part of inout constraints last. 1083f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) { 1084f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson ArgTypes.push_back(InOutArgTypes[i]); 1085f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Args.push_back(InOutArgs[i]); 1086f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson } 1087f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson Constraints += InOutConstraints; 1088f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 1089fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Clobbers 1090fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) { 1091fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson std::string Clobber(S.getClobber(i)->getStrData(), 1092fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.getClobber(i)->getByteLength()); 1093fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1094fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Clobber = Target.getNormalizedGCCRegisterName(Clobber.c_str()); 1095fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1096ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson if (i != 0 || NumConstraints != 0) 1097fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 1098ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson 1099ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson Constraints += "~{"; 1100fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += Clobber; 1101ea041758d49215167e473a515b8d46e77b170ccfAnders Carlsson Constraints += '}'; 1102fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 1103fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1104fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson // Add machine specific clobbers 1105ccf614c479ac93326a01e7b373b30759eed7807fEli Friedman std::string MachineClobbers = Target.getClobbers(); 1106ccf614c479ac93326a01e7b373b30759eed7807fEli Friedman if (!MachineClobbers.empty()) { 1107fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson if (!Constraints.empty()) 1108fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Constraints += ','; 1109ccf614c479ac93326a01e7b373b30759eed7807fEli Friedman Constraints += MachineClobbers; 1110fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson } 1111f39a4211bdea6c136562a5225e5a84d54e62dc8fAnders Carlsson 1112fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson const llvm::FunctionType *FTy = 1113fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::FunctionType::get(ResultType, ArgTypes, false); 1114fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson 1115fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::InlineAsm *IA = 1116fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::InlineAsm::get(FTy, AsmString, Constraints, 1117fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson S.isVolatile() || S.getNumOutputs() == 0); 1118fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson llvm::Value *Result = Builder.CreateCall(IA, Args.begin(), Args.end(), ""); 11191e692ace08959399794363e77499b73da5494af9Eli Friedman if (ResultAddr) // FIXME: volatility 1120fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson Builder.CreateStore(Result, ResultAddr); 1121fb1aeb804c08d5288a923fb278161783e6abdc66Anders Carlsson} 1122