From: Anders Carlsson Date: Fri, 12 Dec 2008 05:52:00 +0000 (+0000) Subject: Work in preparation for VLAs. Make sure to restore the stack if necessary (Saving... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=17d28a3e0b0efaba14534d0e6d6a307283d96b9f;p=clang Work in preparation for VLAs. Make sure to restore the stack if necessary (Saving the stack isn't implemented right now :) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60925 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index 0a67e57e34..1c5cb90cbe 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -16,8 +16,9 @@ #include "CodeGenFunction.h" #include "clang/AST/StmtVisitor.h" #include "clang/Basic/TargetInfo.h" -#include "llvm/InlineAsm.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/InlineAsm.h" +#include "llvm/Intrinsics.h" using namespace clang; using namespace CodeGen; @@ -129,6 +130,9 @@ RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, DI->EmitRegionStart(CurFn, Builder); } + // Push a null stack save value. + StackSaveValues.push_back(0); + for (CompoundStmt::const_body_iterator I = S.body_begin(), E = S.body_end()-GetLast; I != E; ++I) EmitStmt(*I); @@ -139,22 +143,33 @@ RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, DI->EmitRegionEnd(CurFn, Builder); } - if (!GetLast) - return RValue::get(0); + RValue RV; + if (!GetLast) + RV = RValue::get(0); + else { + // We have to special case labels here. They are statements, but when put + // at the end of a statement expression, they yield the value of their + // subexpression. Handle this by walking through all labels we encounter, + // emitting them before we evaluate the subexpr. + const Stmt *LastStmt = S.body_back(); + while (const LabelStmt *LS = dyn_cast(LastStmt)) { + EmitLabel(*LS); + LastStmt = LS->getSubStmt(); + } - // We have to special case labels here. They are statements, but when put at - // the end of a statement expression, they yield the value of their - // subexpression. Handle this by walking through all labels we encounter, - // emitting them before we evaluate the subexpr. - const Stmt *LastStmt = S.body_back(); - while (const LabelStmt *LS = dyn_cast(LastStmt)) { - EmitLabel(*LS); - LastStmt = LS->getSubStmt(); + EnsureInsertPoint(); + + RV = EmitAnyExpr(cast(LastStmt), AggLoc); } - - EnsureInsertPoint(); - return EmitAnyExpr(cast(LastStmt), AggLoc); + if (llvm::Value *V = StackSaveValues.pop_back_val()) { + V = Builder.CreateLoad(V, "tmp"); + + llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stackrestore); + Builder.CreateCall(F, V); + } + + return RV; } void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB, bool IsFinished) { diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 600582c96e..952c3b3c1c 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -166,6 +166,11 @@ private: /// statement range in current switch instruction. llvm::BasicBlock *CaseRangeBlock; + /// StackSaveValues - A stack(!) of stack save values. When a new scope is + /// entered, a null is pushed on this stack. If a VLA is emitted, then + /// the return value of llvm.stacksave() is stored at the top of this stack. + llvm::SmallVector StackSaveValues; + public: CodeGenFunction(CodeGenModule &cgm);