1. pass的概念
在LLVM中优化以pass形式实现, 每一个pass代表一种优化. pass分为两类, 一类是分析(analysis)pass, 负责收集信息共其它pass使用, 辅助调试或使程序可视化; 另一类是变换(transform)pass, 改变程序的dataflow / controlflow. LLVM中实现了几十种优化pass, 其中许多pass运行不止一次. analysis pass存放在lib/Analysis下, transform pass存放在lib/Transforms下. 本文简要介绍其概念, 后文将逐个详细分析.2. 跟踪与调试pass LLVM提供了完善的日志系统来跟踪各个pass的运行.1 [13:38:49] hansy@hansy:~$ cat test.c 2 int sigma(int cnt) 3 { 4 int sum = 0, i = 0; 5 for (i = 0; i < cnt; i++) 6 sum += i; 7 return sum; 8 } 9 10 [13:38:55] hansy@hansy:~$ clang test.c -O2 -mllvm -debug -S 2>test.ll11 [13:39:02] hansy@hansy:~$ clang test.c -O2 -mllvm -debug-only=early-cse -S 2>test.ll12 [13:39:05] hansy@hansy:~$ clang test.c -O2 -mllvm -print-before-all -S 2>test.ll13 [13:39:16] hansy@hansy:~$ clang test.c -O2 -mllvm -print-after-all -S 2>test.ll14 [13:39:25] hansy@hansy:~$ clang test.c -O2 -mllvm -print-after-all -mllvm -filter-print-funcs=sigma -S 2>test.ll
1 #ifndef NDEBUG 2 #define DEBUG_WITH_TYPE(TYPE, X) \ 3 do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType(TYPE)) { X; } \ 4 } while (false) 5 #else 6 #define DEBUG_WITH_TYPE(TYPE, X) do { } while (false) 7 #endif 8 9 #define LLVM_DEBUG(X) DEBUG_WITH_TYPE(DEBUG_TYPE, X)10 11 #ifndef NDEBUG12 static cl::opt13 Debug("debug", cl::desc("Enable debug output"), cl::Hidden,14 cl::location(DebugFlag));15 static cl::opt >16 DebugOnly("debug-only", cl::desc("Enable a specific type of debug output (comma separated list of types)"),17 cl::Hidden, cl::ZeroOrMore, cl::value_desc("debug string"),18 cl::location(DebugOnlyOptLoc), cl::ValueRequired);19 #endif20 21 bool isCurrentDebugType(const char *DebugType) {22 if (CurrentDebugType->empty())23 return true;24 for (auto &d : *CurrentDebugType) {25 if (d == DebugType)26 return true;27 }28 return false;29 }30 31 raw_ostream &llvm::dbgs() {32 static struct dbgstream {33 circular_raw_ostream strm;34 35 dbgstream() :36 strm(errs(), "*** Debug Log Output ***\n",37 (!EnableDebugBuffering || !DebugFlag) ? 0 : DebugBufferSize) {38 if (EnableDebugBuffering && DebugFlag && DebugBufferSize != 0)39 sys::AddSignalHandler(&debug_user_sig_handler, nullptr);40 }41 } thestrm;42 43 return thestrm.strm;44 }
1 if( LLVM_ENABLE_ASSERTIONS ) 2 # MSVC doesn't like _DEBUG on release builds. See PR 4379. 3 if( NOT MSVC ) 4 add_definitions( -D_DEBUG ) 5 endif() 6 # On non-Debug builds cmake automatically defines NDEBUG, so we 7 # explicitly undefine it: 8 if( NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" ) 9 add_definitions( -UNDEBUG )10 # Also remove /D NDEBUG to avoid MSVC warnings about conflicting defines.11 foreach (flags_var_to_scrub12 CMAKE_CXX_FLAGS_RELEASE13 CMAKE_CXX_FLAGS_RELWITHDEBINFO14 CMAKE_CXX_FLAGS_MINSIZEREL15 CMAKE_C_FLAGS_RELEASE16 CMAKE_C_FLAGS_RELWITHDEBINFO17 CMAKE_C_FLAGS_MINSIZEREL)18 string (REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " "19 "${flags_var_to_scrub}" "${${flags_var_to_scrub}}")20 endforeach()21 endif()22 endif()