1f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===- AtomicExpandUtils.h - Utilities for expanding atomic instructions --===//
2f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
3f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//                     The LLVM Compiler Infrastructure
4f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
5f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file is distributed under the University of Illinois Open Source
6f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// License. See LICENSE.TXT for details.
7f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
8f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
9f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
10f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef LLVM_CODEGEN_ATOMICEXPANDUTILS_H
11f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define LLVM_CODEGEN_ATOMICEXPANDUTILS_H
12f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
13f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/STLExtras.h"
14f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/IRBuilder.h"
15f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Support/AtomicOrdering.h"
16f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
17f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace llvm {
18f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
19f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass AtomicRMWInst;
20f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass Value;
21f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
22f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Parameters (see the expansion example below):
23f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// (the builder, %addr, %loaded, %new_val, ordering,
24f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///  /* OUT */ %success, /* OUT */ %new_loaded)
25f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotusing CreateCmpXchgInstFun =
26f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    function_ref<void(IRBuilder<> &, Value *, Value *, Value *, AtomicOrdering,
27f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                      Value *&, Value *&)>;
28f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
29f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Expand an atomic RMW instruction into a loop utilizing
30f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// cmpxchg. You'll want to make sure your target machine likes cmpxchg
31f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// instructions in the first place and that there isn't another, better,
32f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// transformation available (for example AArch32/AArch64 have linked loads).
33f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
34f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// This is useful in passes which can't rewrite the more exotic RMW
35f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// instructions directly into a platform specific intrinsics (because, say,
36f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// those intrinsics don't exist). If such a pass is able to expand cmpxchg
37f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// instructions directly however, then, with this function, it could avoid two
38f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// extra module passes (avoiding passes by `-atomic-expand` and itself). A
39f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// specific example would be PNaCl's `RewriteAtomics` pass.
40f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
41f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Given: atomicrmw some_op iN* %addr, iN %incr ordering
42f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
43f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// The standard expansion we produce is:
44f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///     [...]
45f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///     %init_loaded = load atomic iN* %addr
46f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///     br label %loop
47f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// loop:
48f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///     %loaded = phi iN [ %init_loaded, %entry ], [ %new_loaded, %loop ]
49f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///     %new = some_op iN %loaded, %incr
50f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// ; This is what -atomic-expand will produce using this function on i686
51f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// targets:
52f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///     %pair = cmpxchg iN* %addr, iN %loaded, iN %new_val
53f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///     %new_loaded = extractvalue { iN, i1 } %pair, 0
54f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///     %success = extractvalue { iN, i1 } %pair, 1
55f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// ; End callback produced IR
56f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///     br i1 %success, label %atomicrmw.end, label %loop
57f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// atomicrmw.end:
58f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///     [...]
59f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot///
60f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// Returns true if the containing function was modified.
61f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotbool expandAtomicRMWToCmpXchg(AtomicRMWInst *AI, CreateCmpXchgInstFun Factory);
62f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
63f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // end namespace llvm
64f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
65f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif // LLVM_CODEGEN_ATOMICEXPANDUTILS_H
66