* The stack map is not compiled into the executable.
-Using the LLVM makefiles (like the `sample project
-<http://llvm.org/viewvc/llvm-project/llvm/trunk/projects/sample/>`__), this code
+Using the LLVM makefiles, this code
can be compiled as a plugin using a simple makefile:
.. code-block:: make
Denotes a multithreaded mutator; the collector must still stop the mutator
("stop the world") before beginning reachability analysis. Stopping a
multithreaded mutator is a complicated problem. It generally requires highly
- platform specific code in the runtime, and the production of carefully
+ platform-specific code in the runtime, and the production of carefully
designed machine code at safe points.
Concurrent
Custom lowering of intrinsics: ``CustomRoots``, ``CustomReadBarriers``, and ``CustomWriteBarriers``
---------------------------------------------------------------------------------------------------
-For GCs which use barriers or unusual treatment of stack roots, these flags
-allow the collector to perform arbitrary transformations of the LLVM IR:
+For GCs which use barriers or unusual treatment of stack roots, these
+flags allow the collector to perform arbitrary transformations of the
+LLVM IR:
.. code-block:: c++
CustomReadBarriers = true;
CustomWriteBarriers = true;
}
-
- virtual bool initializeCustomLowering(Module &M);
- virtual bool performCustomLowering(Function &F);
};
-If any of these flags are set, then LLVM suppresses its default lowering for the
-corresponding intrinsics and instead calls ``performCustomLowering``.
-
-LLVM's default action for each intrinsic is as follows:
-
-* ``llvm.gcroot``: Leave it alone. The code generator must see it or the stack
- map will not be computed.
-
-* ``llvm.gcread``: Substitute a ``load`` instruction.
-
-* ``llvm.gcwrite``: Substitute a ``store`` instruction.
-
-If ``CustomReadBarriers`` or ``CustomWriteBarriers`` are specified, then
-``performCustomLowering`` **must** eliminate the corresponding barriers.
-
-``performCustomLowering`` must comply with the same restrictions as
-:ref:`FunctionPass::runOnFunction <writing-an-llvm-pass-runOnFunction>`
-Likewise, ``initializeCustomLowering`` has the same semantics as
-:ref:`Pass::doInitialization(Module&)
-<writing-an-llvm-pass-doInitialization-mod>`
+If any of these flags are set, LLVM suppresses its default lowering for
+the corresponding intrinsics. Instead, you must provide a custom Pass
+which lowers the intrinsics as desired. If you have opted in to custom
+lowering of a particular intrinsic your pass **must** eliminate all
+instances of the corresponding intrinsic in functions which opt in to
+your GC. The best example of such a pass is the ShadowStackGC and it's
+ShadowStackGCLowering pass.
-The following can be used as a template:
-
-.. code-block:: c++
-
- #include "llvm/IR/Module.h"
- #include "llvm/IR/IntrinsicInst.h"
-
- bool MyGC::initializeCustomLowering(Module &M) {
- return false;
- }
-
- bool MyGC::performCustomLowering(Function &F) {
- bool MadeChange = false;
-
- for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
- for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; )
- if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++))
- if (Function *F = CI->getCalledFunction())
- switch (F->getIntrinsicID()) {
- case Intrinsic::gcwrite:
- // Handle llvm.gcwrite.
- CI->eraseFromParent();
- MadeChange = true;
- break;
- case Intrinsic::gcread:
- // Handle llvm.gcread.
- CI->eraseFromParent();
- MadeChange = true;
- break;
- case Intrinsic::gcroot:
- // Handle llvm.gcroot.
- CI->eraseFromParent();
- MadeChange = true;
- break;
- }
-
- return MadeChange;
- }
+There is currently no way to register such a custom lowering pass
+without building a custom copy of LLVM.
.. _safe-points:
X("mygc", "My bespoke garbage collector.");
}
-The collector should use ``AsmPrinter`` and ``TargetAsmInfo`` to print portable
-assembly code to the ``std::ostream``. The collector itself contains the stack
-map for the entire module, and may access the ``GCFunctionInfo`` using its own
-``begin()`` and ``end()`` methods. Here's a realistic example:
+The collector should use ``AsmPrinter`` to print portable assembly code. The
+collector itself contains the stack map for the entire module, and may access
+the ``GCFunctionInfo`` using its own ``begin()`` and ``end()`` methods. Here's
+a realistic example:
.. code-block:: c++
void MyGCPrinter::finishAssembly(AsmPrinter &AP) {
MCStreamer &OS = AP.OutStreamer;
- unsigned IntPtrSize = AP.TM.getDataLayout()->getPointerSize();
+ unsigned IntPtrSize = AP.TM.getSubtargetImpl()->getDataLayout()->getPointerSize();
// Put this in the data section.
OS.SwitchSection(AP.getObjFileLowering().getDataSection());