From 397a98d86df781aaddf64280773657c73ee29435 Mon Sep 17 00:00:00 2001 From: Mark Heffernan Date: Mon, 10 Aug 2015 17:29:39 +0000 Subject: Add new llvm.loop.unroll.enable metadata for use with "#pragma unroll". This change adds the new unroll metadata "llvm.loop.unroll.enable" which directs the optimizer to unroll a loop fully if the trip count is known at compile time, and unroll partially if the trip count is not known at compile time. This differs from "llvm.loop.unroll.full" which explicitly does not unroll a loop if the trip count is not known at compile time With this change "#pragma unroll" generates "llvm.loop.unroll.enable" rather than "llvm.loop.unroll.full" metadata. This changes the semantics of "#pragma unroll" slightly to mean "unroll aggressively (fully or partially)" rather than "unroll fully or not at all". The motivating example for this change was some internal code with a loop marked with "#pragma unroll" which only sometimes had a compile-time trip count depending on template magic. When the trip count was a compile-time constant, everything works as expected and the loop is fully unrolled. However, when the trip count was not a compile-time constant the "#pragma unroll" explicitly disabled unrolling of the loop(!). Removing "#pragma unroll" caused the loop to be unrolled partially which was desirable from a performance perspective. llvm-svn: 244467 --- clang/lib/CodeGen/CGLoopInfo.cpp | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'clang/lib/CodeGen/CGLoopInfo.cpp') diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp index 5bc08f7d52a..0afe7dbb9f1 100644 --- a/clang/lib/CodeGen/CGLoopInfo.cpp +++ b/clang/lib/CodeGen/CGLoopInfo.cpp @@ -67,10 +67,14 @@ static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs) { // Setting unroll.full or unroll.disable if (Attrs.UnrollEnable != LoopAttributes::Unspecified) { - Metadata *Vals[] = { - MDString::get(Ctx, (Attrs.UnrollEnable == LoopAttributes::Enable - ? "llvm.loop.unroll.full" - : "llvm.loop.unroll.disable"))}; + std::string Name; + if (Attrs.UnrollEnable == LoopAttributes::Enable) + Name = "llvm.loop.unroll.enable"; + else if (Attrs.UnrollEnable == LoopAttributes::Full) + Name = "llvm.loop.unroll.full"; + else + Name = "llvm.loop.unroll.disable"; + Metadata *Vals[] = {MDString::get(Ctx, Name)}; Args.push_back(MDNode::get(Ctx, Vals)); } @@ -137,7 +141,7 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, setInterleaveCount(1); break; case LoopHintAttr::Unroll: - setUnrollEnable(false); + setUnrollState(LoopAttributes::Disable); break; case LoopHintAttr::UnrollCount: case LoopHintAttr::VectorizeWidth: @@ -153,7 +157,7 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, setVectorizeEnable(true); break; case LoopHintAttr::Unroll: - setUnrollEnable(true); + setUnrollState(LoopAttributes::Enable); break; case LoopHintAttr::UnrollCount: case LoopHintAttr::VectorizeWidth: @@ -178,7 +182,21 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, break; } break; - case LoopHintAttr::Default: + case LoopHintAttr::Full: + switch (Option) { + case LoopHintAttr::Unroll: + setUnrollState(LoopAttributes::Full); + break; + case LoopHintAttr::Vectorize: + case LoopHintAttr::Interleave: + case LoopHintAttr::UnrollCount: + case LoopHintAttr::VectorizeWidth: + case LoopHintAttr::InterleaveCount: + llvm_unreachable("Options cannot be used with 'full' hint."); + break; + } + break; + case LoopHintAttr::Numeric: switch (Option) { case LoopHintAttr::VectorizeWidth: setVectorizeWidth(ValueInt); @@ -190,13 +208,9 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, setUnrollCount(ValueInt); break; case LoopHintAttr::Unroll: - // The default option is used when '#pragma unroll' is specified. - setUnrollEnable(true); - break; case LoopHintAttr::Vectorize: case LoopHintAttr::Interleave: - llvm_unreachable("Options cannot be assigned a value and do not have a " - "default value."); + llvm_unreachable("Options cannot be assigned a value."); break; } break; -- cgit v1.2.3