X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=docs%2FProgrammersManual.html;h=e920cbbc6460d54ac21bd5094e93bb824a08d58e;hb=f72596c04a06458c6152a51c9678690a34d59ab8;hp=253e836361015576ce5d538474ae0a0373ddfdbe;hpb=714257f5deec6049a4170bdd77ca1c3df989d67e;p=oota-llvm.git diff --git a/docs/ProgrammersManual.html b/docs/ProgrammersManual.html index 253e8363610..e920cbbc646 100644 --- a/docs/ProgrammersManual.html +++ b/docs/ProgrammersManual.html @@ -2,6 +2,7 @@ "http://www.w3.org/TR/html4/strict.dtd">
+Written by Chris Lattner, Dinakar Dhurjati, Gabor Greif, - Joel Stanley and - Reid Spencer
+ Joel Stanley, + Reid Spencer and + Owen Anderson @@ -413,6 +435,107 @@ are lots of examples in the LLVM source base. + + + + +Although LLVM generally does not do much string manipulation, we do have +several important APIs which take strings. Two important examples are the +Value class -- which has names for instructions, functions, etc. -- and the +StringMap class which is used extensively in LLVM and Clang.
+ +These are generic classes, and they need to be able to accept strings which +may have embedded null characters. Therefore, they cannot simply take +a const char *, and taking a const std::string& requires +clients to perform a heap allocation which is usually unnecessary. Instead, +many LLVM APIs use a const StringRef& or a const +Twine& for passing strings efficiently.
+ +The StringRef data type represents a reference to a constant string +(a character array and a length) and supports the common operations available +on std:string, but does not require heap allocation.
+ +It can be implicitly constructed using a C style null-terminated string, +an std::string, or explicitly with a character pointer and length. +For example, the StringRef find function is declared as:
+ +and clients can call it using any one of:
+ ++ Map.find("foo"); // Lookup "foo" + Map.find(std::string("bar")); // Lookup "bar" + Map.find(StringRef("\0baz", 4)); // Lookup "\0baz" ++
Similarly, APIs which need to return a string may return a StringRef +instance, which can be used directly or converted to an std::string +using the str member function. See +"llvm/ADT/StringRef.h" +for more information.
+ +You should rarely use the StringRef class directly, because it contains +pointers to external memory it is not generally safe to store an instance of the +class (unless you know that the external storage will not be freed).
+ +The Twine class is an efficient way for APIs to accept concatenated +strings. For example, a common LLVM paradigm is to name one instruction based on +the name of another instruction with a suffix, for example:
+ ++ New = CmpInst::Create(..., SO->getName() + ".cmp"); ++
The Twine class is effectively a +lightweight rope +which points to temporary (stack allocated) objects. Twines can be implicitly +constructed as the result of the plus operator applied to strings (i.e., a C +strings, an std::string, or a StringRef). The twine delays the +actual concatentation of strings until it is actually required, at which point +it can be efficiently rendered directly into a character array. This avoids +unnecessary heap allocation involved in constructing the temporary results of +string concatenation. See +"llvm/ADT/Twine.h" +for more information.
+ +As with a StringRef, Twine objects point to external memory +and should almost never be stored or mentioned directly. They are intended +solely for use when defining a function which should be able to efficiently +accept concatenated strings.
+ +-DOUT << "I am here!\n"; +DEBUG(errs() << "I am here!\n");
-DOUT << "No debug type\n"; #undef DEBUG_TYPE +DEBUG(errs() << "No debug type\n"); #define DEBUG_TYPE "foo" -DOUT << "'foo' debug type\n"; +DEBUG(errs() << "'foo' debug type\n"); #undef DEBUG_TYPE #define DEBUG_TYPE "bar" -DOUT << "'bar' debug type\n"; +DEBUG(errs() << "'bar' debug type\n")); #undef DEBUG_TYPE #define DEBUG_TYPE "" -DOUT << "No debug type (2)\n"; +DEBUG(errs() << "No debug type (2)\n");
The DEBUG_WITH_TYPE macro is also available for situations where you +would like to set DEBUG_TYPE, but only for one specific DEBUG +statement. It takes an additional first parameter, which is the type to use. For +example, the preceeding example could be written as:
+ + ++DEBUG_WITH_TYPE("", errs() << "No debug type\n"); +DEBUG_WITH_TYPE("foo", errs() << "'foo' debug type\n"); +DEBUG_WITH_TYPE("bar", errs() << "'bar' debug type\n")); +DEBUG_WITH_TYPE("", errs() << "No debug type (2)\n"); ++
+TODO: const char* vs stringref vs smallstring vs std::string. Describe twine, +xref to #string_apis. +
+ +In generating IR, you may need some complex types. If you know these types -statically, you can use TypeBuilder<...>::get(), defined +statically, you can use TypeBuilder<...>::get(), defined in llvm/Support/TypeBuilder.h, to retrieve them. TypeBuilder has two forms depending on whether you're building types for cross-compilation -or native library use. TypeBuilder<T, true> requires +or native library use. TypeBuilder<T, true> requires that T be independent of the host environment, meaning that it's built out of types from the llvm::types namespace and pointers, functions, arrays, etc. built of -those. TypeBuilder<T, false> additionally allows native C types +those. TypeBuilder<T, false> additionally allows native C types whose size may depend on the host compiler. For example,
-FunctionType *ft = TypeBuilder<types::i<8>(types::i<32>*), true>::get(); +FunctionType *ft = TypeBuilder<types::i<8>(types::i<32>*), true>::get();
-std::vector@@ -2129,6 +2285,123 @@ comment for more details.params; +std::vector<const Type*> params; params.push_back(PointerType::getUnqual(Type::Int32Ty)); FunctionType *ft = FunctionType::get(Type::Int8Ty, params, false);
+This section describes the interaction of the LLVM APIs with multithreading, +both on the part of client applications, and in the JIT, in the hosted +application. +
+ ++Note that LLVM's support for multithreading is still relatively young. Up +through version 2.5, the execution of threaded hosted applications was +supported, but not threaded client access to the APIs. While this use case is +now supported, clients must adhere to the guidelines specified below to +ensure proper operation in multithreaded mode. +
+ ++Note that, on Unix-like platforms, LLVM requires the presence of GCC's atomic +intrinsics in order to support threaded operation. If you need a +multhreading-capable LLVM on a platform without a suitably modern system +compiler, consider compiling LLVM and LLVM-GCC in single-threaded mode, and +using the resultant compiler to build a copy of LLVM with multithreading +support. +
++In order to properly protect its internal data structures while avoiding +excessive locking overhead in the single-threaded case, the LLVM must intialize +certain data structures necessary to provide guards around its internals. To do +so, the client program must invoke llvm_start_multithreaded() before +making any concurrent LLVM API calls. To subsequently tear down these +structures, use the llvm_stop_multithreaded() call. You can also use +the llvm_is_multithreaded() call to check the status of multithreaded +mode. +
+ ++Note that both of these calls must be made in isolation. That is to +say that no other LLVM API calls may be executing at any time during the +execution of llvm_start_multithreaded() or llvm_stop_multithreaded +. It's is the client's responsibility to enforce this isolation. +
+ ++The return value of llvm_start_multithreaded() indicates the success or +failure of the initialization. Failure typically indicates that your copy of +LLVM was built without multithreading support, typically because GCC atomic +intrinsics were not found in your system compiler. In this case, the LLVM API +will not be safe for concurrent calls. However, it will be safe for +hosting threaded applications in the JIT, though care must be taken to ensure +that side exits and the like do not accidentally result in concurrent LLVM API +calls. +
++When you are done using the LLVM APIs, you should call llvm_shutdown() +to deallocate memory used for internal structures. This will also invoke +llvm_stop_multithreaded() if LLVM is operating in multithreaded mode. +As such, llvm_shutdown() requires the same isolation guarantees as +llvm_stop_multithreaded(). +
+ ++Note that, if you use scope-based shutdown, you can use the +llvm_shutdown_obj class, which calls llvm_shutdown() in its +destructor. +
+ManagedStatic is a utility class in LLVM used to implement static +initialization of static resources, such as the global type tables. Before the +invocation of llvm_shutdown(), it implements a simple lazy +initialization scheme. Once llvm_start_multithreaded() returns, +however, it uses double-checked locking to implement thread-safe lazy +initialization. +
+ ++Note that, because no other threads are allowed to issue LLVM API calls before +llvm_start_multithreaded() returns, it is possible to have +ManagedStatics of llvm::sys::Mutexs. +
+ ++The llvm_acquire_global_lock() and llvm_release_global_lock +APIs provide access to the global lock used to implement the double-checked +locking for lazy initialization. These should only be used internally to LLVM, +and only if you know what you're doing! +
+#include "llvm/BasicBlock.h"
-doxygen info: BasicBlock
+doxygen info: BasicBlock
Class
Superclass: Value