void InstrumentMemoryAccesses::visitAtomicRMWInst(AtomicRMWInst &I) { // Instrument an AtomicRMW instruction with a store check. Value *AccessSize = ConstantInt::get(SizeTy, TD->getTypeStoreSize(I.getType())); instrument(I.getPointerOperand(), AccessSize, StoreCheckFunction, I); ++AtomicsInstrumented; }
LLVMValueRef LLVM_General_BuildAtomicRMW( LLVMBuilderRef b, LLVMAtomicRMWBinOp rmwOp, LLVMValueRef ptr, LLVMValueRef val, LLVMBool v, LLVMAtomicOrdering lao, LLVMSynchronizationScope lss, const char *name ) { AtomicRMWInst *a = unwrap(b)->CreateAtomicRMW( unwrap(rmwOp), unwrap(ptr), unwrap(val), unwrap(lao), unwrap(lss) ); a->setVolatile(v); a->setName(name); return wrap(a); }
/// %res = atomicrmw OP T* %ptr, T %val memory_order /// becomes: /// %res = call T @llvm.nacl.atomic.rmw.i<size>(OP, %ptr, %val, memory_order) void AtomicVisitor::visitAtomicRMWInst(AtomicRMWInst &I) { return; // XXX EMSCRIPTEN NaCl::AtomicRMWOperation Op; switch (I.getOperation()) { default: report_fatal_error("unsupported atomicrmw operation: " + ToStr(I)); case AtomicRMWInst::Add: Op = NaCl::AtomicAdd; break; case AtomicRMWInst::Sub: Op = NaCl::AtomicSub; break; case AtomicRMWInst::And: Op = NaCl::AtomicAnd; break; case AtomicRMWInst::Or: Op = NaCl::AtomicOr; break; case AtomicRMWInst::Xor: Op = NaCl::AtomicXor; break; case AtomicRMWInst::Xchg: Op = NaCl::AtomicExchange; break; } PointerHelper<AtomicRMWInst> PH(*this, I); const NaCl::AtomicIntrinsics::AtomicIntrinsic *Intrinsic = findAtomicIntrinsic(I, Intrinsic::nacl_atomic_rmw, PH.PET); checkSizeMatchesType(I, PH.BitSize, I.getValOperand()->getType()); Value *Args[] = {ConstantInt::get(Type::getInt32Ty(C), Op), PH.P, I.getValOperand(), freezeMemoryOrder(I, I.getOrdering())}; replaceInstructionWithIntrinsicCall(I, Intrinsic, PH.OriginalPET, PH.PET, Args); }
void GraphBuilder::visitAtomicRMWInst(AtomicRMWInst &I) { // // Create a DSNode for the dereferenced pointer . If the DSNode is NULL, do // nothing more (this can occur if the pointer is a NULL constant; bugpoint // can generate such code). // DSNodeHandle Ptr = getValueDest(I.getPointerOperand()); if (Ptr.isNull()) return; // // Make that the memory object is read and written. // Ptr.getNode()->setReadMarker(); Ptr.getNode()->setModifiedMarker(); // // Modify the DSNode so that it has the loaded/written type at the // appropriate offset. // Ptr.getNode()->growSizeForType(I.getType(), Ptr.getOffset()); Ptr.getNode()->mergeTypeInfo(I.getType(), Ptr.getOffset()); return; }