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