From: Peizhao Ou Date: Thu, 5 Apr 2018 22:42:56 +0000 (-0700) Subject: Reverts unnecessary changes X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=refs%2Fheads%2Frelaxed-stores-insert-dmb;p=oota-llvm.git Reverts unnecessary changes --- diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index fd786f68fb6..3d58c499823 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -124,10 +124,6 @@ private: /// is only computed once and is cached. mutable MCSymbol *CachedMCSymbol = nullptr; - // XXX-update: A flag that checks whether we can eliminate this machine basic - // block. - bool canEliminateMachineBB; - // Intrusive list support MachineBasicBlock() {} @@ -139,15 +135,6 @@ private: friend class MachineFunction; public: - // XXX-update: - void disableCanEliminateMachineBB() { - canEliminateMachineBB = false; - } - - bool getCanEliminateMachineBB() { - return canEliminateMachineBB; - } - /// Return the LLVM basic block that this instance corresponded to originally. /// Note that this may be NULL if this instance does not correspond directly /// to an LLVM basic block. diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h index 94edb547f53..c6b54d308ce 100644 --- a/include/llvm/IR/BasicBlock.h +++ b/include/llvm/IR/BasicBlock.h @@ -59,9 +59,6 @@ private: InstListType InstList; Function *Parent; - // XXX-update: A flag that checks whether we can eliminate this block. - bool canEliminateBlock; - void setParent(Function *parent); friend class SymbolTableListTraits; @@ -77,16 +74,6 @@ private: Function *Parent = nullptr, BasicBlock *InsertBefore = nullptr); public: - // XXX-update: - void disableCanEliminateBlock() { - canEliminateBlock = false; - } - - bool getCanEliminateBlock() { - return canEliminateBlock; - } - - /// \brief Get the context in which this basic block lives. LLVMContext &getContext() const; diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index cc6c25974cd..28e1fd90fdf 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -228,14 +228,6 @@ public: LoadInst(Value *Ptr, const char *NameStr, bool isVolatile, BasicBlock *InsertAtEnd); - bool getHasSubsequentAcqlRMW() { - return hasSubsequentAcqlRMW_; - } - - void setHasSubsequentAcqlRMW(bool val) { - hasSubsequentAcqlRMW_ = val; - } - /// isVolatile - Return true if this is a load from a volatile memory /// location. /// @@ -314,8 +306,6 @@ private: void setInstructionSubclassData(unsigned short D) { Instruction::setInstructionSubclassData(D); } - - bool hasSubsequentAcqlRMW_; }; //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/AtomicExpandPass.cpp b/lib/CodeGen/AtomicExpandPass.cpp index 9647fb9e5d5..d12fdb24698 100644 --- a/lib/CodeGen/AtomicExpandPass.cpp +++ b/lib/CodeGen/AtomicExpandPass.cpp @@ -15,11 +15,6 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/SetOperations.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Analysis/MemoryLocation.h" #include "llvm/CodeGen/AtomicExpandUtils.h" #include "llvm/CodeGen/Passes.h" #include "llvm/IR/Function.h" @@ -28,13 +23,11 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" -#include "llvm/IR/NoFolder.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetSubtargetInfo.h" -#include "llvm/Transforms/Utils/BasicBlockUtils.h" using namespace llvm; @@ -71,33 +64,6 @@ namespace { bool isIdempotentRMW(AtomicRMWInst *AI); bool simplifyIdempotentRMW(AtomicRMWInst *AI); }; - - - // If 'LI' is a relaxed load, and it is immediately followed by a -// atomic read-modify-write that has acq_rel parameter, we don't have to do -// anything since the rmw serves as a natural barrier. -void MarkRelaxedLoadBeforeAcqrelRMW(LoadInst* LI) { - auto* BB = LI->getParent(); - auto BBI = LI->getIterator(); - for (BBI++; BBI != BB->end(); BBI++) { - Instruction* CurInst = &*BBI; - if (!CurInst) { - return; - } - if (!CurInst->isAtomic()) { - continue; - } - auto* RMW = dyn_cast(CurInst); - if (!RMW) { - return; - } - if (RMW->getOrdering() == AcquireRelease || - RMW->getOrdering() == SequentiallyConsistent) { - LI->setHasSubsequentAcqlRMW(true); - } - } -} - } char AtomicExpand::ID = 0; @@ -116,64 +82,15 @@ bool AtomicExpand::runOnFunction(Function &F) { TLI = TM->getSubtargetImpl(F)->getTargetLowering(); SmallVector AtomicInsts; - SmallVector MonotonicLoadInsts; - bool MadeChange = false; // Changing control-flow while iterating through it is a bad idea, so gather a // list of all atomic instructions before we start. for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { - // XXX-update: For relaxed loads, change them to acquire. This includes - // relaxed loads, relaxed atomic RMW & relaxed atomic compare exchange. - if (I->isAtomic()) { - switch (I->getOpcode()) { - case Instruction::AtomicCmpXchg: { - // XXX-comment: AtomicCmpXchg in AArch64 will be translated to a - // conditional branch that contains the value of the load anyway, so - // we don't need to do anything. - /* - auto* CmpXchg = dyn_cast(&*I); - auto SuccOrdering = CmpXchg->getSuccessOrdering(); - if (SuccOrdering == Monotonic) { - CmpXchg->setSuccessOrdering(Acquire); - } else if (SuccOrdering == Release) { - CmpXchg->setSuccessOrdering(AcquireRelease); - } - */ - break; - } - case Instruction::AtomicRMW: { - // XXX-comment: Similar to AtomicCmpXchg. These instructions in - // AArch64 will be translated to a loop whose condition depends on the - // store status, which further depends on the load value. - /* - auto* RMW = dyn_cast(&*I); - if (RMW->getOrdering() == Monotonic) { - RMW->setOrdering(Acquire); - } - */ - break; - } - case Instruction::Load: { - auto* LI = dyn_cast(&*I); - if (LI->getOrdering() == Monotonic) { - /* - DEBUG(dbgs() << "Transforming relaxed loads to acquire loads: " - << *LI << '\n'); - LI->setOrdering(Acquire); - */ -// MonotonicLoadInsts.push_back(LI); - MarkRelaxedLoadBeforeAcqrelRMW(LI); - } - break; - } - default: { - break; - } - } + if (I->isAtomic()) AtomicInsts.push_back(&*I); - } } + bool MadeChange = false; for (auto I : AtomicInsts) { auto LI = dyn_cast(I); auto SI = dyn_cast(I); @@ -187,7 +104,7 @@ bool AtomicExpand::runOnFunction(Function &F) { if (TLI->getInsertFencesForAtomic()) { if (LI && isAtLeastAcquire(LI->getOrdering())) { FenceOrdering = LI->getOrdering(); -// AddFakeConditionalBranch( + LI->setOrdering(Monotonic); IsStore = false; IsLoad = true; } else if (SI && isAtLeastRelease(SI->getOrdering())) { @@ -255,7 +172,6 @@ bool AtomicExpand::runOnFunction(Function &F) { MadeChange |= expandAtomicCmpXchg(CASI); } } - return MadeChange; } diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index a56fec468cc..df5cac5a9f7 100644 --- a/lib/CodeGen/BranchFolding.cpp +++ b/lib/CodeGen/BranchFolding.cpp @@ -1116,12 +1116,6 @@ bool BranchFolder::OptimizeBranches(MachineFunction &MF) { for (MachineFunction::iterator I = std::next(MF.begin()), E = MF.end(); I != E; ) { MachineBasicBlock *MBB = &*I++; - // XXX-disabled: Don't optimize blocks that contain intentionally added fake - // conditional branch. - if (!MBB->getCanEliminateMachineBB()) { - continue; - } - MadeChange |= OptimizeBlock(MBB); // If it is dead, remove it. diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp index bb183b4d6dc..c8007a524e7 100644 --- a/lib/CodeGen/CodeGenPrepare.cpp +++ b/lib/CodeGen/CodeGenPrepare.cpp @@ -15,13 +15,9 @@ #include "llvm/CodeGen/Passes.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/InstructionSimplify.h" -#include "llvm/Analysis/MemoryLocation.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/ValueTracking.h" @@ -34,12 +30,9 @@ #include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InlineAsm.h" -#include "llvm/IR/InstIterator.h" -#include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/MDBuilder.h" -#include "llvm/IR/NoFolder.h" #include "llvm/IR/PatternMatch.h" #include "llvm/IR/Statepoint.h" #include "llvm/IR/ValueHandle.h" @@ -154,15 +147,10 @@ class TypePromotionTransaction; /// DataLayout for the Function being processed. const DataLayout *DL; - // XXX-comment:We need DominatorTree to figure out which instruction to - // taint. - DominatorTree *DT; - public: static char ID; // Pass identification, replacement for typeid explicit CodeGenPrepare(const TargetMachine *TM = nullptr) - : FunctionPass(ID), TM(TM), TLI(nullptr), TTI(nullptr), DL(nullptr), - DT(nullptr) { + : FunctionPass(ID), TM(TM), TLI(nullptr), TTI(nullptr), DL(nullptr) { initializeCodeGenPreparePass(*PassRegistry::getPassRegistry()); } bool runOnFunction(Function &F) override; @@ -173,7 +161,6 @@ class TypePromotionTransaction; AU.addPreserved(); AU.addRequired(); AU.addRequired(); - AU.addRequired(); } private: @@ -208,1109 +195,20 @@ class TypePromotionTransaction; } char CodeGenPrepare::ID = 0; -INITIALIZE_TM_PASS_BEGIN(CodeGenPrepare, "codegenprepare", - "Optimize for code generation", false, false) -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_TM_PASS_END(CodeGenPrepare, "codegenprepare", +INITIALIZE_TM_PASS(CodeGenPrepare, "codegenprepare", "Optimize for code generation", false, false) FunctionPass *llvm::createCodeGenPreparePass(const TargetMachine *TM) { return new CodeGenPrepare(TM); } -namespace { - -bool StoreAddressDependOnValue(StoreInst* SI, Value* DepVal); -Value* GetUntaintedAddress(Value* CurrentAddress); - -// The depth we trace down a variable to look for its dependence set. -const unsigned kDependenceDepth = 4; - -// Recursively looks for variables that 'Val' depends on at the given depth -// 'Depth', and adds them in 'DepSet'. If 'InsertOnlyLeafNodes' is true, only -// inserts the leaf node values; otherwise, all visited nodes are included in -// 'DepSet'. Note that constants will be ignored. -template -void recursivelyFindDependence(SetType* DepSet, Value* Val, - bool InsertOnlyLeafNodes = false, - unsigned Depth = kDependenceDepth) { - if (Val == nullptr) { - return; - } - if (!InsertOnlyLeafNodes && !isa(Val)) { - DepSet->insert(Val); - } - if (Depth == 0) { - // Cannot go deeper. Insert the leaf nodes. - if (InsertOnlyLeafNodes && !isa(Val)) { - DepSet->insert(Val); - } - return; - } - - // Go one step further to explore the dependence of the operands. - Instruction* I = nullptr; - if ((I = dyn_cast(Val))) { - if (isa(I)) { - // A load is considerd the leaf load of the dependence tree. Done. - DepSet->insert(Val); - return; - } else if (I->isBinaryOp()) { - BinaryOperator* I = dyn_cast(Val); - Value *Op0 = I->getOperand(0), *Op1 = I->getOperand(1); - recursivelyFindDependence(DepSet, Op0, InsertOnlyLeafNodes, Depth - 1); - recursivelyFindDependence(DepSet, Op1, InsertOnlyLeafNodes, Depth - 1); - } else if (I->isCast()) { - Value* Op0 = I->getOperand(0); - recursivelyFindDependence(DepSet, Op0, InsertOnlyLeafNodes, Depth - 1); - } else if (I->getOpcode() == Instruction::Select) { - Value* Op0 = I->getOperand(0); - Value* Op1 = I->getOperand(1); - Value* Op2 = I->getOperand(2); - recursivelyFindDependence(DepSet, Op0, InsertOnlyLeafNodes, Depth - 1); - recursivelyFindDependence(DepSet, Op1, InsertOnlyLeafNodes, Depth - 1); - recursivelyFindDependence(DepSet, Op2, InsertOnlyLeafNodes, Depth - 1); - } else if (I->getOpcode() == Instruction::GetElementPtr) { - for (unsigned i = 0; i < I->getNumOperands(); i++) { - recursivelyFindDependence(DepSet, I->getOperand(i), InsertOnlyLeafNodes, - Depth - 1); - } - } else if (I->getOpcode() == Instruction::Store) { - auto* SI = dyn_cast(Val); - recursivelyFindDependence(DepSet, SI->getPointerOperand(), - InsertOnlyLeafNodes, Depth - 1); - recursivelyFindDependence(DepSet, SI->getValueOperand(), - InsertOnlyLeafNodes, Depth - 1); - } else { - Value* Op0 = nullptr; - Value* Op1 = nullptr; - switch (I->getOpcode()) { - case Instruction::ICmp: - case Instruction::FCmp: { - Op0 = I->getOperand(0); - Op1 = I->getOperand(1); - recursivelyFindDependence(DepSet, Op0, InsertOnlyLeafNodes, - Depth - 1); - recursivelyFindDependence(DepSet, Op1, InsertOnlyLeafNodes, - Depth - 1); - break; - } - case Instruction::PHI: { - for (int i = 0; i < I->getNumOperands(); i++) { - auto* op = I->getOperand(i); - if (DepSet->count(op) == 0) { - recursivelyFindDependence(DepSet, I->getOperand(i), - InsertOnlyLeafNodes, Depth - 1); - } - } - break; - } - default: { - // Be conservative. Add it and be done with it. - DepSet->insert(Val); - return; - } - } - } - } else if (isa(Val)) { - // Not interested in constant values. Done. - return; - } else { - // Be conservative. Add it and be done with it. - DepSet->insert(Val); - return; - } -} - -// Helper function to create a Cast instruction. -Value* createCast(IRBuilder& Builder, Value* DepVal, - Type* TargetIntegerType) { - Instruction::CastOps CastOp = Instruction::BitCast; - switch (DepVal->getType()->getTypeID()) { - case Type::IntegerTyID: { - assert(TargetIntegerType->getTypeID() == Type::IntegerTyID); - auto* FromType = dyn_cast(DepVal->getType()); - auto* ToType = dyn_cast(TargetIntegerType); - assert(FromType && ToType); - if (FromType->getBitWidth() <= ToType->getBitWidth()) { - CastOp = Instruction::ZExt; - } else { - CastOp = Instruction::Trunc; - } - break; - } - case Type::FloatTyID: - case Type::DoubleTyID: { - CastOp = Instruction::FPToSI; - break; - } - case Type::PointerTyID: { - CastOp = Instruction::PtrToInt; - break; - } - default: { break; } - } - - return Builder.CreateCast(CastOp, DepVal, TargetIntegerType); -} - -// Given a value, if it's a tainted address, this function returns the -// instruction that ORs the "dependence value" with the "original address". -// Otherwise, returns nullptr. This instruction is the first OR instruction -// where one of its operand is an AND instruction with an operand being 0. -// -// E.g., it returns '%4 = or i32 %3, %2' given 'CurrentAddress' is '%5'. -// %0 = load i32, i32* @y, align 4, !tbaa !1 -// %cmp = icmp ne i32 %0, 42 // <== this is like the condition -// %1 = sext i1 %cmp to i32 -// %2 = ptrtoint i32* @x to i32 -// %3 = and i32 %1, 0 -// %4 = or i32 %3, %2 -// %5 = inttoptr i32 %4 to i32* -// store i32 1, i32* %5, align 4 -Instruction* getOrAddress(Value* CurrentAddress) { - // Is it a cast from integer to pointer type. - Instruction* OrAddress = nullptr; - Instruction* AndDep = nullptr; - Instruction* CastToInt = nullptr; - Value* ActualAddress = nullptr; - Constant* ZeroConst = nullptr; - - const Instruction* CastToPtr = dyn_cast(CurrentAddress); - if (CastToPtr && CastToPtr->getOpcode() == Instruction::IntToPtr) { - // Is it an OR instruction: %1 = or %and, %actualAddress. - if ((OrAddress = dyn_cast(CastToPtr->getOperand(0))) && - OrAddress->getOpcode() == Instruction::Or) { - // The first operand should be and AND instruction. - AndDep = dyn_cast(OrAddress->getOperand(0)); - if (AndDep && AndDep->getOpcode() == Instruction::And) { - // Also make sure its first operand of the "AND" is 0, or the "AND" is - // marked explicitly by "NoInstCombine". - if ((ZeroConst = dyn_cast(AndDep->getOperand(1))) && - ZeroConst->isNullValue()) { - return OrAddress; - } - } - } - } - // Looks like it's not been tainted. - return nullptr; -} - -// Given a value, if it's a tainted address, this function returns the -// instruction that taints the "dependence value". Otherwise, returns nullptr. -// This instruction is the last AND instruction where one of its operand is 0. -// E.g., it returns '%3' given 'CurrentAddress' is '%5'. -// %0 = load i32, i32* @y, align 4, !tbaa !1 -// %cmp = icmp ne i32 %0, 42 // <== this is like the condition -// %1 = sext i1 %cmp to i32 -// %2 = ptrtoint i32* @x to i32 -// %3 = and i32 %1, 0 -// %4 = or i32 %3, %2 -// %5 = inttoptr i32 %4 to i32* -// store i32 1, i32* %5, align 4 -Instruction* getAndDependence(Value* CurrentAddress) { - // If 'CurrentAddress' is tainted, get the OR instruction. - auto* OrAddress = getOrAddress(CurrentAddress); - if (OrAddress == nullptr) { - return nullptr; - } - - // No need to check the operands. - auto* AndDepInst = dyn_cast(OrAddress->getOperand(0)); - assert(AndDepInst); - return AndDepInst; -} - -// Given a value, if it's a tainted address, this function returns -// the "dependence value", which is the first operand in the AND instruction. -// E.g., it returns '%1' given 'CurrentAddress' is '%5'. -// %0 = load i32, i32* @y, align 4, !tbaa !1 -// %cmp = icmp ne i32 %0, 42 // <== this is like the condition -// %1 = sext i1 %cmp to i32 -// %2 = ptrtoint i32* @x to i32 -// %3 = and i32 %1, 0 -// %4 = or i32 %3, %2 -// %5 = inttoptr i32 %4 to i32* -// store i32 1, i32* %5, align 4 -Value* getDependence(Value* CurrentAddress) { - auto* AndInst = getAndDependence(CurrentAddress); - if (AndInst == nullptr) { - return nullptr; - } - return AndInst->getOperand(0); -} - -// Given an address that has been tainted, returns the only condition it depends -// on, if any; otherwise, returns nullptr. -Value* getConditionDependence(Value* Address) { - auto* Dep = getDependence(Address); - if (Dep == nullptr) { - // 'Address' has not been dependence-tainted. - return nullptr; - } - - Value* Operand = Dep; - while (true) { - auto* Inst = dyn_cast(Operand); - if (Inst == nullptr) { - // Non-instruction type does not have condition dependence. - return nullptr; - } - if (Inst->getOpcode() == Instruction::ICmp) { - return Inst; - } else { - if (Inst->getNumOperands() != 1) { - return nullptr; - } else { - Operand = Inst->getOperand(0); - } - } - } -} - -// Conservatively decides whether the dependence set of 'Val1' includes the -// dependence set of 'Val2'. If 'ExpandSecondValue' is false, we do not expand -// 'Val2' and use that single value as its dependence set. -// If it returns true, it means the dependence set of 'Val1' includes that of -// 'Val2'; otherwise, it only means we cannot conclusively decide it. -bool dependenceSetInclusion(Value* Val1, Value* Val2, - int Val1ExpandLevel = 2 * kDependenceDepth, - int Val2ExpandLevel = kDependenceDepth) { - typedef SmallSet IncludingSet; - typedef SmallSet IncludedSet; - - IncludingSet DepSet1; - IncludedSet DepSet2; - // Look for more depths for the including set. - recursivelyFindDependence(&DepSet1, Val1, false /*Insert all visited nodes*/, - Val1ExpandLevel); - recursivelyFindDependence(&DepSet2, Val2, true /*Only insert leaf nodes*/, - Val2ExpandLevel); - - auto set_inclusion = [](IncludingSet FullSet, IncludedSet Subset) { - for (auto* Dep : Subset) { - if (0 == FullSet.count(Dep)) { - return false; - } - } - return true; - }; - bool inclusion = set_inclusion(DepSet1, DepSet2); - DEBUG(dbgs() << "[dependenceSetInclusion]: " << inclusion << "\n"); - DEBUG(dbgs() << "Including set for: " << *Val1 << "\n"); - DEBUG(for (const auto* Dep : DepSet1) { dbgs() << "\t\t" << *Dep << "\n"; }); - DEBUG(dbgs() << "Included set for: " << *Val2 << "\n"); - DEBUG(for (const auto* Dep : DepSet2) { dbgs() << "\t\t" << *Dep << "\n"; }); - - return inclusion; -} - -// Recursively iterates through the operands spawned from 'DepVal'. If there -// exists a single value that 'DepVal' only depends on, we call that value the -// root dependence of 'DepVal' and return it. Otherwise, return 'DepVal'. -Value* getRootDependence(Value* DepVal) { - SmallSet DepSet; - for (unsigned depth = kDependenceDepth; depth > 0; --depth) { - recursivelyFindDependence(&DepSet, DepVal, true /*Only insert leaf nodes*/, - depth); - if (DepSet.size() == 1) { - return *DepSet.begin(); - } - DepSet.clear(); - } - return DepVal; -} - -// This function actually taints 'DepVal' to the address to 'SI'. If the -// address -// of 'SI' already depends on whatever 'DepVal' depends on, this function -// doesn't do anything and returns false. Otherwise, returns true. -// -// This effect forces the store and any stores that comes later to depend on -// 'DepVal'. For example, we have a condition "cond", and a store instruction -// "s: STORE addr, val". If we want "s" (and any later store) to depend on -// "cond", we do the following: -// %conv = sext i1 %cond to i32 -// %addrVal = ptrtoint i32* %addr to i32 -// %andCond = and i32 conv, 0; -// %orAddr = or i32 %andCond, %addrVal; -// %NewAddr = inttoptr i32 %orAddr to i32*; -// -// This is a more concrete example: -// ------ -// %0 = load i32, i32* @y, align 4, !tbaa !1 -// %cmp = icmp ne i32 %0, 42 // <== this is like the condition -// %1 = sext i1 %cmp to i32 -// %2 = ptrtoint i32* @x to i32 -// %3 = and i32 %1, 0 -// %4 = or i32 %3, %2 -// %5 = inttoptr i32 %4 to i32* -// store i32 1, i32* %5, align 4 -bool taintStoreAddress(StoreInst* SI, Value* DepVal) { - // Set the insertion point right after the 'DepVal'. - Instruction* Inst = nullptr; - IRBuilder Builder(SI); - BasicBlock* BB = SI->getParent(); - Value* Address = SI->getPointerOperand(); - Type* TargetIntegerType = - IntegerType::get(Address->getContext(), - BB->getModule()->getDataLayout().getPointerSizeInBits()); - - // Does SI's address already depends on whatever 'DepVal' depends on? - if (StoreAddressDependOnValue(SI, DepVal)) { - return false; - } - - // Figure out if there's a root variable 'DepVal' depends on. For example, we - // can extract "getelementptr inbounds %struct, %struct* %0, i64 0, i32 123" - // to be "%struct* %0" since all other operands are constant. - auto* RootVal = getRootDependence(DepVal); - auto* RootInst = dyn_cast(RootVal); - auto* DepValInst = dyn_cast(DepVal); - if (RootInst && DepValInst && - RootInst->getParent() == DepValInst->getParent()) { - DepVal = RootVal; - } - - // Is this already a dependence-tainted store? - Value* OldDep = getDependence(Address); - if (OldDep) { - // The address of 'SI' has already been tainted. Just need to absorb the - // DepVal to the existing dependence in the address of SI. - Instruction* AndDep = getAndDependence(Address); - IRBuilder Builder(AndDep); - Value* NewDep = nullptr; - if (DepVal->getType() == AndDep->getType()) { - NewDep = Builder.CreateAnd(OldDep, DepVal); - } else { - NewDep = Builder.CreateAnd( - OldDep, createCast(Builder, DepVal, TargetIntegerType)); - } - - auto* NewDepInst = dyn_cast(NewDep); - - // Use the new AND instruction as the dependence - AndDep->setOperand(0, NewDep); - return true; - } - - // SI's address has not been tainted. Now taint it with 'DepVal'. - Value* CastDepToInt = createCast(Builder, DepVal, TargetIntegerType); - Value* PtrToIntCast = Builder.CreatePtrToInt(Address, TargetIntegerType); - Value* AndDepVal = - Builder.CreateAnd(CastDepToInt, ConstantInt::get(TargetIntegerType, 0)); - auto AndInst = dyn_cast(AndDepVal); - // XXX-comment: The original IR InstCombiner would change our and instruction - // to a select and then the back end optimize the condition out. We attach a - // flag to instructions and set it here to inform the InstCombiner to not to - // touch this and instruction at all. - Value* OrAddr = Builder.CreateOr(AndDepVal, PtrToIntCast); - Value* NewAddr = Builder.CreateIntToPtr(OrAddr, Address->getType()); - - DEBUG(dbgs() << "[taintStoreAddress]\n" - << "Original store: " << *SI << '\n'); - SI->setOperand(1, NewAddr); - - // Debug output. - DEBUG(dbgs() << "\tTargetIntegerType: " << *TargetIntegerType << '\n' - << "\tCast dependence value to integer: " << *CastDepToInt - << '\n' - << "\tCast address to integer: " << *PtrToIntCast << '\n' - << "\tAnd dependence value: " << *AndDepVal << '\n' - << "\tOr address: " << *OrAddr << '\n' - << "\tCast or instruction to address: " << *NewAddr << "\n\n"); - - return true; -} - -// Looks for the previous store in the if block --- 'BrBB', which makes the -// speculative store 'StoreToHoist' safe. -Value* getSpeculativeStoreInPrevBB(StoreInst* StoreToHoist, BasicBlock* BrBB) { - assert(StoreToHoist && "StoreToHoist must be a real store"); - - Value* StorePtr = StoreToHoist->getPointerOperand(); - - // Look for a store to the same pointer in BrBB. - for (BasicBlock::reverse_iterator RI = BrBB->rbegin(), RE = BrBB->rend(); - RI != RE; ++RI) { - Instruction* CurI = &*RI; - - StoreInst* SI = dyn_cast(CurI); - // Found the previous store make sure it stores to the same location. - // XXX-update: If the previous store's original untainted address are the - // same as 'StorePtr', we are also good to hoist the store. - if (SI && (SI->getPointerOperand() == StorePtr || - GetUntaintedAddress(SI->getPointerOperand()) == StorePtr)) { - // Found the previous store, return its value operand. - return SI; - } - } - - assert(false && - "We should not reach here since this store is safe to speculate"); -} - -// XXX-comment: Returns true if it changes the code, false otherwise (the branch -// condition already depends on 'DepVal'. -bool taintConditionalBranch(BranchInst* BI, Value* DepVal) { - assert(BI->isConditional()); - auto* Cond = BI->getOperand(0); - if (dependenceSetInclusion(Cond, DepVal)) { - // The dependence/ordering is self-evident. - return false; - } - - IRBuilder Builder(BI); - auto* AndDep = - Builder.CreateAnd(DepVal, ConstantInt::get(DepVal->getType(), 0)); - auto* TruncAndDep = - Builder.CreateTrunc(AndDep, IntegerType::get(DepVal->getContext(), 1)); - auto* OrCond = Builder.CreateOr(TruncAndDep, Cond); - BI->setOperand(0, OrCond); - - // Debug output. - DEBUG(dbgs() << "\tTainted branch condition:\n" << *BI->getParent()); - - return true; -} - -bool ConditionalBranchDependsOnValue(BranchInst* BI, Value* DepVal) { - assert(BI->isConditional()); - auto* Cond = BI->getOperand(0); - return dependenceSetInclusion(Cond, DepVal); -} - -// XXX-update: For a relaxed load 'LI', find the first immediate atomic store or -// the first conditional branch. Returns nullptr if there's no such immediately -// following store/branch instructions, which we can only enforce the load with -// 'acquire'. 'ChainedBB' contains all the blocks chained together with -// unconditional branches from 'BB' to the block with the first store/cond -// branch. -template -Instruction* findFirstStoreCondBranchInst(LoadInst* LI, Vector* ChainedBB) { - // In some situations, relaxed loads can be left as is: - // 1. The relaxed load is used to calculate the address of the immediate - // following store; - // 2. The relaxed load is used as a condition in the immediate following - // condition, and there are no stores in between. This is actually quite - // common. E.g., - // int r1 = x.load(relaxed); - // if (r1 != 0) { - // y.store(1, relaxed); - // } - // However, in this function, we don't deal with them directly. Instead, we - // just find the immediate following store/condition branch and return it. - - assert(ChainedBB != nullptr && "Chained BB should not be nullptr"); - auto* BB = LI->getParent(); - ChainedBB->push_back(BB); - auto BE = BB->end(); - auto BBI = BasicBlock::iterator(LI); - BBI++; - while (true) { - for (; BBI != BE; BBI++) { - Instruction* Inst = &*BBI; - IntrinsicInst* II = dyn_cast(&*BBI); - if (II && II->getIntrinsicID() == Intrinsic::aarch64_stlxr) { - return II; - } else if (Inst->getOpcode() == Instruction::Store) { - return Inst; - } else if (Inst->getOpcode() == Instruction::Br) { - auto* BrInst = dyn_cast(Inst); - if (BrInst->isConditional()) { - return Inst; - } else { - // Reinitialize iterators with the destination of the unconditional - // branch. - BB = BrInst->getSuccessor(0); - ChainedBB->push_back(BB); - BBI = BB->begin(); - BE = BB->end(); - break; - } - } - } - if (BBI == BE) { - return nullptr; - } - } -} - -// XXX-update: Find the next node of the last relaxed load from 'FromInst' to -// 'ToInst'. If none, return 'ToInst'. -Instruction* findLastLoadNext(Instruction* FromInst, Instruction* ToInst) { - if (FromInst == ToInst) { - return ToInst; - } - Instruction* LastLoad = ToInst; - auto* BB = FromInst->getParent(); - auto BE = BB->end(); - auto BBI = BasicBlock::iterator(FromInst); - BBI++; - for (; BBI != BE && &*BBI != ToInst; BBI++) { - auto* LI = dyn_cast(&*BBI); - if (LI == nullptr || !LI->isAtomic() || LI->getOrdering() != Monotonic) { - continue; - } - LastLoad = LI; - LastLoad = LastLoad->getNextNode(); - } - return LastLoad; -} - -// Inserts a fake conditional branch right after the instruction 'SplitInst', -// and the branch condition is 'Condition'. 'SplitInst' will be placed in the -// newly created block. -void AddFakeConditionalBranch(Instruction* SplitInst, Value* Condition) { - auto* BB = SplitInst->getParent(); - TerminatorInst* ThenTerm = nullptr; - TerminatorInst* ElseTerm = nullptr; - SplitBlockAndInsertIfThenElse(Condition, SplitInst, &ThenTerm, &ElseTerm); - assert(ThenTerm && ElseTerm && - "Then/Else terminators cannot be empty after basic block spliting"); - auto* ThenBB = ThenTerm->getParent(); - auto* ElseBB = ElseTerm->getParent(); - auto* TailBB = ThenBB->getSingleSuccessor(); - assert(TailBB && "Tail block cannot be empty after basic block spliting"); - - ThenBB->disableCanEliminateBlock(); - ThenBB->disableCanEliminateBlock(); - TailBB->disableCanEliminateBlock(); - ThenBB->setName(BB->getName() + "Then.Fake"); - ElseBB->setName(BB->getName() + "Else.Fake"); - DEBUG(dbgs() << "Add fake conditional branch:\n" - << "Then Block:\n" - << *ThenBB << "Else Block:\n" - << *ElseBB << "\n"); -} - -// Returns true if the code is changed, and false otherwise. -void TaintRelaxedLoads(Instruction* UsageInst, Instruction* InsertPoint) { - // For better performance, we can add a "AND X 0" instruction before the - // condition. - auto* BB = UsageInst->getParent(); - if (InsertPoint == nullptr) { - InsertPoint = UsageInst->getNextNode(); - } - // Insert instructions after PHI nodes. - while (dyn_cast(InsertPoint)) { - InsertPoint = InsertPoint->getNextNode(); - } - // First thing is to cast 'UsageInst' to an integer type if necessary. - Value* AndTarget = nullptr; - Type* TargetIntegerType = - IntegerType::get(UsageInst->getContext(), - BB->getModule()->getDataLayout().getPointerSizeInBits()); - - // Check whether InsertPoint is a added fake conditional branch. - BranchInst* BI = nullptr; - if ((BI = dyn_cast(InsertPoint)) && BI->isConditional()) { - auto* Cond = dyn_cast(BI->getOperand(0)); - if (Cond && Cond->getOpcode() == Instruction::ICmp) { - auto* CmpInst = dyn_cast(Cond); - auto* Op0 = dyn_cast(Cond->getOperand(0)); - auto* Op1 = dyn_cast(Cond->getOperand(1)); - // %tmp = And X, 0 - // %cmp = ICMP_NE %tmp, 0 - // Br %cmp - // => - // %tmp1 = And X, NewTaintedVal - // %tmp2 = And %tmp1, 0 - // %cmp = ICMP_NE %tmp2, 0 - // Br %cmp - if (CmpInst && CmpInst->getPredicate() == CmpInst::ICMP_NE && Op0 && - Op0->getOpcode() == Instruction::And && Op1 && Op1->isZero()) { - auto* Op01 = dyn_cast(Op0->getOperand(1)); - if (Op01 && Op01->isZero()) { - // Now we have a previously added fake cond branch. - auto* Op00 = Op0->getOperand(0); - IRBuilder Builder(CmpInst); - if (Op00->getType() == UsageInst->getType()) { - AndTarget = UsageInst; - } else { - AndTarget = createCast(Builder, UsageInst, Op00->getType()); - } - AndTarget = Builder.CreateAnd(Op00, AndTarget); - auto* AndZero = dyn_cast(Builder.CreateAnd( - AndTarget, Constant::getNullValue(AndTarget->getType()))); - CmpInst->setOperand(0, AndZero); - return; - } - } - } - } - - IRBuilder Builder(InsertPoint); - if (IntegerType::classof(UsageInst->getType())) { - AndTarget = UsageInst; - } else { - AndTarget = createCast(Builder, UsageInst, TargetIntegerType); - } - auto* AndZero = dyn_cast( - Builder.CreateAnd(AndTarget, Constant::getNullValue(AndTarget->getType()))); - auto* FakeCondition = dyn_cast(Builder.CreateICmp( - CmpInst::ICMP_NE, AndZero, Constant::getNullValue(AndTarget->getType()))); - AddFakeConditionalBranch(FakeCondition->getNextNode(), FakeCondition); -} - -// XXX-comment: Finds the appropriate Value derived from an atomic load. -// 'ChainedBB' contains all the blocks chained together with unconditional -// branches from LI's parent BB to the block with the first store/cond branch. -// If we don't find any, it means 'LI' is not used at all (which should not -// happen in practice). We can simply set 'LI' to be acquire just to be safe. -template -Instruction* findMostRecentDependenceUsage(LoadInst* LI, Instruction* LaterInst, - Vector* ChainedBB, - DominatorTree* DT) { - typedef SmallSet UsageSet; - typedef DenseMap> UsageMap; - assert(ChainedBB->size() >= 1 && "ChainedBB must have >=1 size"); - // Mapping from basic block in 'ChainedBB' to the set of dependence usage of - // 'LI' in each block. - UsageMap usage_map; - auto* LoadBB = LI->getParent(); - usage_map[LoadBB] = make_unique(); - usage_map[LoadBB]->insert(LI); - - for (auto* BB : *ChainedBB) { - if (usage_map[BB] == nullptr) { - usage_map[BB] = make_unique(); - } - auto& usage_set = usage_map[BB]; - if (usage_set->size() == 0) { - // The value has not been used. - return nullptr; - } - // Calculate the usage in the current BB first. - std::list bb_usage_list; - std::copy(usage_set->begin(), usage_set->end(), - std::back_inserter(bb_usage_list)); - for (auto list_iter = bb_usage_list.begin(); - list_iter != bb_usage_list.end(); list_iter++) { - auto* val = *list_iter; - for (auto* U : val->users()) { - Instruction* Inst = nullptr; - if (!(Inst = dyn_cast(U))) { - continue; - } - assert(Inst && "Usage value must be an instruction"); - auto iter = - std::find(ChainedBB->begin(), ChainedBB->end(), Inst->getParent()); - if (iter == ChainedBB->end()) { - // Only care about usage within ChainedBB. - continue; - } - auto* UsageBB = *iter; - if (UsageBB == BB) { - // Current BB. - if (!usage_set->count(Inst)) { - bb_usage_list.push_back(Inst); - usage_set->insert(Inst); - } - } else { - // A following BB. - if (usage_map[UsageBB] == nullptr) { - usage_map[UsageBB] = make_unique(); - } - usage_map[UsageBB]->insert(Inst); - } - } - } - } - - // Pick one usage that is in LaterInst's block and that dominates 'LaterInst'. - auto* LaterBB = LaterInst->getParent(); - auto& usage_set = usage_map[LaterBB]; - Instruction* usage_inst = nullptr; - for (auto* inst : *usage_set) { - if (DT->dominates(inst, LaterInst)) { - usage_inst = inst; - break; - } - } - - assert(usage_inst && "The usage instruction in the same block but after the " - "later instruction"); - return usage_inst; -} - -// XXX-comment: Returns whether the code has been changed. -bool AddFakeConditionalBranchAfterMonotonicLoads( - SmallSet& MonotonicLoadInsts, DominatorTree* DT) { - bool Changed = false; - while (!MonotonicLoadInsts.empty()) { - auto* LI = *MonotonicLoadInsts.begin(); - MonotonicLoadInsts.erase(LI); - SmallVector ChainedBB; - auto* FirstInst = findFirstStoreCondBranchInst(LI, &ChainedBB); - if (FirstInst != nullptr) { - if (FirstInst->getOpcode() == Instruction::Store) { - if (StoreAddressDependOnValue(dyn_cast(FirstInst), LI)) { - continue; - } - } else if (FirstInst->getOpcode() == Instruction::Br) { - if (ConditionalBranchDependsOnValue(dyn_cast(FirstInst), - LI)) { - continue; - } - } else { - IntrinsicInst* II = dyn_cast(FirstInst); - if (!II || II->getIntrinsicID() != Intrinsic::aarch64_stlxr) { - dbgs() << "FirstInst=" << *FirstInst << "\n"; - assert(false && "findFirstStoreCondBranchInst() should return a " - "store/condition branch instruction"); - } - } - } - - // We really need to process the relaxed load now. - StoreInst* SI = nullptr; - IntrinsicInst* II = nullptr; - if (FirstInst) { - SI = dyn_cast(FirstInst); - II = dyn_cast(FirstInst); - } - if (FirstInst && - (SI || (II && II->getIntrinsicID() == Intrinsic::aarch64_stlxr))) { - // For immediately coming stores, taint the address of the store. - if (FirstInst->getParent() == LI->getParent() || - DT->dominates(LI, FirstInst)) { - TaintRelaxedLoads(LI, FirstInst); - Changed = true; - } else { - auto* Inst = - findMostRecentDependenceUsage(LI, FirstInst, &ChainedBB, DT); - if (!Inst) { - LI->setOrdering(Acquire); - Changed = true; - } else { - TaintRelaxedLoads(Inst, FirstInst); - Changed = true; - } - } - } else { - // No upcoming branch - if (!FirstInst) { - TaintRelaxedLoads(LI, nullptr); - Changed = true; - } else { - // For immediately coming branch, directly add a fake branch. - if (FirstInst->getParent() == LI->getParent() || - DT->dominates(LI, FirstInst)) { - TaintRelaxedLoads(LI, FirstInst); - Changed = true; - } else { - auto* Inst = - findMostRecentDependenceUsage(LI, FirstInst, &ChainedBB, DT); - if (Inst) { - TaintRelaxedLoads(Inst, FirstInst); - } else { - LI->setOrdering(Acquire); - } - Changed = true; - } - } - } - } - return Changed; -} - -// XXX-comment: Returns whether the code has been changed. -bool ConvertMonotonicLoadsToAcquire(SmallSet& MonotonicLoadInsts) -{ - bool Changed = false; - while (!MonotonicLoadInsts.empty()) { - auto* LI = *MonotonicLoadInsts.begin(); - MonotonicLoadInsts.erase(LI); - SmallVector ChainedBB; - auto* FirstInst = findFirstStoreCondBranchInst(LI, &ChainedBB); - if (FirstInst != nullptr) { - if (FirstInst->getOpcode() == Instruction::Store) { - if (StoreAddressDependOnValue(dyn_cast(FirstInst), LI)) { - continue; - } - } else if (FirstInst->getOpcode() == Instruction::Br) { - if (ConditionalBranchDependsOnValue(dyn_cast(FirstInst), - LI)) { - continue; - } - } else { - IntrinsicInst* II = dyn_cast(FirstInst); - if (!II || II->getIntrinsicID() != Intrinsic::aarch64_stlxr) { - dbgs() << "FirstInst=" << *FirstInst << "\n"; - assert(false && "findFirstStoreCondBranchInst() should return a " - "store/condition branch instruction"); - } - } - } - - // We really need convert the load to acquire. - LI->setOrdering(Acquire); - } - return Changed; -} - -/**** Implementations of public methods for dependence tainting ****/ -Value* GetUntaintedAddress(Value* CurrentAddress) { - auto* OrAddress = getOrAddress(CurrentAddress); - if (OrAddress == nullptr) { - // Is it tainted by a select instruction? - auto* Inst = dyn_cast(CurrentAddress); - if (nullptr != Inst && Inst->getOpcode() == Instruction::Select) { - // A selection instruction. - if (Inst->getOperand(1) == Inst->getOperand(2)) { - return Inst->getOperand(1); - } - } - - return CurrentAddress; - } - Value* ActualAddress = nullptr; - - auto* CastToInt = dyn_cast(OrAddress->getOperand(1)); - if (CastToInt && CastToInt->getOpcode() == Instruction::PtrToInt) { - return CastToInt->getOperand(0); - } else { - // This should be a IntToPtr constant expression. - ConstantExpr* PtrToIntExpr = - dyn_cast(OrAddress->getOperand(1)); - if (PtrToIntExpr && PtrToIntExpr->getOpcode() == Instruction::PtrToInt) { - return PtrToIntExpr->getOperand(0); - } - } - - // Looks like it's not been dependence-tainted. Returns itself. - return CurrentAddress; -} - -MemoryLocation GetUntaintedMemoryLocation(StoreInst* SI) { - AAMDNodes AATags; - SI->getAAMetadata(AATags); - const auto& DL = SI->getModule()->getDataLayout(); - const auto* OriginalAddr = GetUntaintedAddress(SI->getPointerOperand()); - DEBUG(if (OriginalAddr != SI->getPointerOperand()) { - dbgs() << "[GetUntaintedMemoryLocation]\n" - << "Storing address: " << *SI->getPointerOperand() - << "\nUntainted address: " << *OriginalAddr << "\n"; - }); - return MemoryLocation(OriginalAddr, - DL.getTypeStoreSize(SI->getValueOperand()->getType()), - AATags); -} - -bool TaintDependenceToStore(StoreInst* SI, Value* DepVal) { - if (dependenceSetInclusion(SI, DepVal)) { - return false; - } - - bool tainted = taintStoreAddress(SI, DepVal); - assert(tainted); - return tainted; -} - -bool TaintDependenceToStoreAddress(StoreInst* SI, Value* DepVal) { - if (dependenceSetInclusion(SI->getPointerOperand(), DepVal)) { - return false; - } - - bool tainted = taintStoreAddress(SI, DepVal); - assert(tainted); - return tainted; -} - -bool CompressTaintedStore(BasicBlock* BB) { - // This function looks for windows of adajcent stores in 'BB' that satisfy the - // following condition (and then do optimization): - // *Addr(d1) = v1, d1 is a condition and is the only dependence the store's - // address depends on && Dep(v1) includes Dep(d1); - // *Addr(d2) = v2, d2 is a condition and is the only dependnece the store's - // address depends on && Dep(v2) includes Dep(d2) && - // Dep(d2) includes Dep(d1); - // ... - // *Addr(dN) = vN, dN is a condition and is the only dependence the store's - // address depends on && Dep(dN) includes Dep(d"N-1"). - // - // As a result, Dep(dN) includes [Dep(d1) V ... V Dep(d"N-1")], so we can - // safely transform the above to the following. In between these stores, we - // can omit untainted stores to the same address 'Addr' since they internally - // have dependence on the previous stores on the same address. - // => - // *Addr = v1 - // *Addr = v2 - // *Addr(d3) = v3 - for (auto BI = BB->begin(), BE = BB->end(); BI != BE; BI++) { - // Look for the first store in such a window of adajacent stores. - auto* FirstSI = dyn_cast(&*BI); - if (!FirstSI) { - continue; - } - - // The first store in the window must be tainted. - auto* UntaintedAddress = GetUntaintedAddress(FirstSI->getPointerOperand()); - if (UntaintedAddress == FirstSI->getPointerOperand()) { - continue; - } - - // The first store's address must directly depend on and only depend on a - // condition. - auto* FirstSIDepCond = getConditionDependence(FirstSI->getPointerOperand()); - if (nullptr == FirstSIDepCond) { - continue; - } - - // Dep(first store's storing value) includes Dep(tainted dependence). - if (!dependenceSetInclusion(FirstSI->getValueOperand(), FirstSIDepCond)) { - continue; - } - - // Look for subsequent stores to the same address that satisfy the condition - // of "compressing the dependence". - SmallVector AdajacentStores; - AdajacentStores.push_back(FirstSI); - auto BII = BasicBlock::iterator(FirstSI); - for (BII++; BII != BE; BII++) { - auto* CurrSI = dyn_cast(&*BII); - if (!CurrSI) { - if (BII->mayHaveSideEffects()) { - // Be conservative. Instructions with side effects are similar to - // stores. - break; - } - continue; - } - - auto* OrigAddress = GetUntaintedAddress(CurrSI->getPointerOperand()); - auto* CurrSIDepCond = getConditionDependence(CurrSI->getPointerOperand()); - // All other stores must satisfy either: - // A. 'CurrSI' is an untainted store to the same address, or - // B. the combination of the following 5 subconditions: - // 1. Tainted; - // 2. Untainted address is the same as the group's address; - // 3. The address is tainted with a sole value which is a condition; - // 4. The storing value depends on the condition in 3. - // 5. The condition in 3 depends on the previous stores dependence - // condition. - - // Condition A. Should ignore this store directly. - if (OrigAddress == CurrSI->getPointerOperand() && - OrigAddress == UntaintedAddress) { - continue; - } - // Check condition B. - Value* Cond = nullptr; - if (OrigAddress == CurrSI->getPointerOperand() || - OrigAddress != UntaintedAddress || CurrSIDepCond == nullptr || - !dependenceSetInclusion(CurrSI->getValueOperand(), CurrSIDepCond)) { - // Check condition 1, 2, 3 & 4. - break; - } - - // Check condition 5. - StoreInst* PrevSI = AdajacentStores[AdajacentStores.size() - 1]; - auto* PrevSIDepCond = getConditionDependence(PrevSI->getPointerOperand()); - assert(PrevSIDepCond && - "Store in the group must already depend on a condtion"); - if (!dependenceSetInclusion(CurrSIDepCond, PrevSIDepCond)) { - break; - } - - AdajacentStores.push_back(CurrSI); - } - - if (AdajacentStores.size() == 1) { - // The outer loop should keep looking from the next store. - continue; - } - - // Now we have such a group of tainted stores to the same address. - DEBUG(dbgs() << "[CompressTaintedStore]\n"); - DEBUG(dbgs() << "Original BB\n"); - DEBUG(dbgs() << *BB << '\n'); - auto* LastSI = AdajacentStores[AdajacentStores.size() - 1]; - for (unsigned i = 0; i < AdajacentStores.size() - 1; ++i) { - auto* SI = AdajacentStores[i]; - - // Use the original address for stores before the last one. - SI->setOperand(1, UntaintedAddress); - - DEBUG(dbgs() << "Store address has been reversed: " << *SI << '\n';); - } - // XXX-comment: Try to make the last store use fewer registers. - // If LastSI's storing value is a select based on the condition with which - // its address is tainted, transform the tainted address to a select - // instruction, as follows: - // r1 = Select Cond ? A : B - // r2 = Cond & 0 - // r3 = Addr | r2 - // *r3 = r1 - // ==> - // r1 = Select Cond ? A : B - // r2 = Select Cond ? Addr : Addr - // *r2 = r1 - // The idea is that both Select instructions depend on the same condition, - // so hopefully the backend can generate two cmov instructions for them (and - // this saves the number of registers needed). - auto* LastSIDep = getConditionDependence(LastSI->getPointerOperand()); - auto* LastSIValue = dyn_cast(LastSI->getValueOperand()); - if (LastSIValue && LastSIValue->getOpcode() == Instruction::Select && - LastSIValue->getOperand(0) == LastSIDep) { - // XXX-comment: Maybe it's better for us to just leave it as an and/or - // dependence pattern. - // /* - IRBuilder Builder(LastSI); - auto* Address = - Builder.CreateSelect(LastSIDep, UntaintedAddress, UntaintedAddress); - LastSI->setOperand(1, Address); - DEBUG(dbgs() << "The last store becomes :" << *LastSI << "\n\n";); - // */ - } - } - - return true; -} - -bool PassDependenceToStore(Value* OldAddress, StoreInst* NewStore) { - Value* OldDep = getDependence(OldAddress); - // Return false when there's no dependence to pass from the OldAddress. - if (!OldDep) { - return false; - } - - // No need to pass the dependence to NewStore's address if it already depends - // on whatever 'OldAddress' depends on. - if (StoreAddressDependOnValue(NewStore, OldDep)) { - return false; - } - return taintStoreAddress(NewStore, OldAddress); -} - -SmallSet FindDependence(Value* Val) { - SmallSet DepSet; - recursivelyFindDependence(&DepSet, Val, true /*Only insert leaf nodes*/); - return DepSet; -} - -bool StoreAddressDependOnValue(StoreInst* SI, Value* DepVal) { - return dependenceSetInclusion(SI->getPointerOperand(), DepVal); -} - -bool StoreDependOnValue(StoreInst* SI, Value* Dep) { - return dependenceSetInclusion(SI, Dep); -} - -} // namespace - - - bool CodeGenPrepare::runOnFunction(Function &F) { - bool EverMadeChange = false; - if (skipOptnoneFunction(F)) return false; DL = &F.getParent()->getDataLayout(); + bool EverMadeChange = false; // Clear per function information. InsertedInsts.clear(); PromotedInsts.clear(); @@ -1320,7 +218,6 @@ bool CodeGenPrepare::runOnFunction(Function &F) { TLI = TM->getSubtargetImpl(F)->getTargetLowering(); TLInfo = &getAnalysis().getTLI(); TTI = &getAnalysis().getTTI(F); - DT = &getAnalysis().getDomTree(); OptSize = F.optForSize(); /// This optimization identifies DIV instructions that can be @@ -1419,6 +316,7 @@ bool CodeGenPrepare::runOnFunction(Function &F) { for (auto &I : Statepoints) EverMadeChange |= simplifyOffsetableRelocate(*I); } + return EverMadeChange; } @@ -1465,6 +363,7 @@ bool CodeGenPrepare::eliminateMostlyEmptyBlocks(Function &F) { // Note that this intentionally skips the entry block. for (Function::iterator I = std::next(F.begin()), E = F.end(); I != E;) { BasicBlock *BB = &*I++; + // If this block doesn't end with an uncond branch, ignore it. BranchInst *BI = dyn_cast(BB->getTerminator()); if (!BI || !BI->isUnconditional()) @@ -1512,7 +411,7 @@ bool CodeGenPrepare::canMergeBlocks(const BasicBlock *BB, const Instruction *UI = cast(U); if (UI->getParent() != DestBB || !isa(UI)) return false; - // IfUser is inside DestBB block and it is a PHINode then check + // If User is inside DestBB block and it is a PHINode then check // incoming value. If incoming value is not from BB then this is // a complex condition (e.g. preheaders) we want to avoid here. if (UI->getParent() == DestBB) { diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp index 42190168742..85d544d9498 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -40,7 +40,7 @@ using namespace llvm; #define DEBUG_TYPE "codegen" MachineBasicBlock::MachineBasicBlock(MachineFunction &MF, const BasicBlock *B) - : BB(B), Number(-1), xParent(&MF), canEliminateMachineBB(true) { + : BB(B), Number(-1), xParent(&MF) { Insts.Parent = this; } diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index f119023d217..c741982bc08 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -924,62 +924,6 @@ CommitTargetLoweringOpt(const TargetLowering::TargetLoweringOpt &TLO) { bool DAGCombiner::SimplifyDemandedBits(SDValue Op, const APInt &Demanded) { TargetLowering::TargetLoweringOpt TLO(DAG, LegalTypes, LegalOperations); APInt KnownZero, KnownOne; - - // XXX-disabled: - auto Opcode = Op.getOpcode(); - if (Opcode == ISD::AND || Opcode == ISD::OR) { - auto* Op1 = Op.getOperand(0).getNode(); - auto* Op2 = Op.getOperand(1).getNode(); - auto* Op1C = dyn_cast(Op1); - auto* Op2C = dyn_cast(Op2); - - // and X, 0 - if (Opcode == ISD::AND && !Op1C && Op2C && Op2C->isNullValue()) { - return false; - } - - // or (and X, 0), Y - if (Opcode == ISD::OR) { - if (Op1->getOpcode() == ISD::AND) { - auto* Op11 = Op1->getOperand(0).getNode(); - auto* Op12 = Op1->getOperand(1).getNode(); - auto* Op11C = dyn_cast(Op11); - auto* Op12C = dyn_cast(Op12); - if (!Op11C && Op12C && Op12C->isNullValue()) { - return false; - } - } - if (Op1->getOpcode() == ISD::TRUNCATE) { - // or (trunc (and %0, 0)), Y - auto* Op11 = Op1->getOperand(0).getNode(); - if (Op11->getOpcode() == ISD::AND) { - auto* Op111 = Op11->getOperand(0).getNode(); - auto* Op112 = Op11->getOperand(1).getNode(); - auto* Op111C = dyn_cast(Op111); - auto* Op112C = dyn_cast(Op112); - if (!Op111C && Op112C && Op112C->isNullValue()) { - // or (and X, 0), Y - return false; - } - } - } - } - } - - // trunc (and X, 0) - if (Opcode == ISD::TRUNCATE) { - auto* Op1 = Op.getOperand(0).getNode(); - if (Op1->getOpcode() == ISD::AND) { - auto* Op11 = Op1->getOperand(0).getNode(); - auto* Op12 = Op1->getOperand(1).getNode(); - auto* Op11C = dyn_cast(Op11); - auto* Op12C = dyn_cast(Op12); - if (!Op11C && Op12C && Op12C->isNullValue()) { - return false; - } - } - } - if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne, TLO)) return false; @@ -3098,22 +3042,6 @@ SDValue DAGCombiner::visitAND(SDNode *N) { // fold (and c1, c2) -> c1&c2 ConstantSDNode *N0C = getAsNonOpaqueConstant(N0); ConstantSDNode *N1C = dyn_cast(N1); - - // XXX-disabled: (and x, 0) should not be folded. - // (and (and x, 0), y) shouldn't either. - if (!N0C && N1C && N1C->isNullValue()) { - return SDValue(); - } - if (!N0C) { - if (N0.getOpcode() == ISD::AND) { - auto* N01 = N0.getOperand(1).getNode(); - auto* N01C = dyn_cast(N01); - if (N01C && N01C->isNullValue()) { - return SDValue(); - } - } - } - if (N0C && N1C && !N1C->isOpaque()) return DAG.FoldConstantArithmetic(ISD::AND, SDLoc(N), VT, N0C, N1C); // canonicalize constant to RHS diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index e845a9919ef..893871f9448 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3465,14 +3465,10 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, assert(VT.isInteger() && "This operator does not apply to FP types!"); assert(N1.getValueType() == N2.getValueType() && N1.getValueType() == VT && "Binary operator types must match!"); - - // XXX-disabled: - /* // (X & 0) -> 0. This commonly occurs when legalizing i64 values, so it's // worth handling here. if (N2C && N2C->isNullValue()) return N2; - */ if (N2C && N2C->isAllOnesValue()) // X & -1 -> X return N1; break; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 491d7ec451c..c075da4738a 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -645,50 +645,6 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) { // at this point. FuncInfo->clear(); - // XXX-update: Right after instruction selection, check through the - // intentionally added fake conditional branches and mark them as unremovable. - for (auto& MBB : *MF) { - // Check whether MBB has two successors which only contains an unconditional - // branch to the same destination. - if (MBB.succ_size() != 2 || - !MBB.getLastNonDebugInstr()->isUnconditionalBranch()) { - continue; - } - auto MBBSuccIter = MBB.succ_begin(); - auto* Succ1 = *MBBSuccIter; - MBBSuccIter++; - auto* Succ2 = *MBBSuccIter; - - MachineBasicBlock* Succ1Succ = nullptr; - MachineBasicBlock* Succ2Succ = nullptr; - if ((Succ1->size() == 1 && Succ1->begin()->isUnconditionalBranch()) || - (Succ1->size() == 0)) { - if (Succ1->succ_size()) { - Succ1Succ = *Succ1->succ_begin(); - } - } - if ((Succ2->size() == 1 && Succ2->begin()->isUnconditionalBranch()) || - (Succ2->size() == 0)) { - if (Succ1->succ_size()) { - Succ2Succ = *Succ2->succ_begin(); - } - } - - bool HasCommonDest = Succ1Succ && Succ1Succ == Succ2Succ; - if (HasCommonDest) { - auto MBBIter = MBB.end(); - std::advance(MBBIter, -2); - assert(MBBIter->isConditionalBranch()); - MBB.disableCanEliminateMachineBB(); - Succ1->disableCanEliminateMachineBB(); - Succ2->disableCanEliminateMachineBB(); - Succ1Succ->disableCanEliminateMachineBB(); - DEBUG(dbgs() << "Mark as unremovable machine basic block: " << MBB - << "\nMark as unremovable branch instruction: " << *MBBIter - << "\n"); - } - } - DEBUG(dbgs() << "*** MachineFunction at end of ISel ***\n"); DEBUG(MF->print(dbgs())); diff --git a/lib/IR/BasicBlock.cpp b/lib/IR/BasicBlock.cpp index 8e3cac27f48..f61276fd436 100644 --- a/lib/IR/BasicBlock.cpp +++ b/lib/IR/BasicBlock.cpp @@ -40,8 +40,7 @@ template class llvm::SymbolTableListTraits; BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent, BasicBlock *InsertBefore) - : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(nullptr), - canEliminateBlock(true) { + : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(nullptr) { if (NewParent) insertInto(NewParent, InsertBefore); diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 37b56f8efc7..9198b0e1fb5 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -1974,10 +1974,6 @@ void Verifier::visitBasicBlock(BasicBlock &BB) { "PHI nodes must have at least one entry. If the block is dead, " "the PHI should be removed!", PN); - if (PN->getNumIncomingValues() != Preds.size()) { - dbgs() << "Problematic function: \n" << *PN->getParent()->getParent() << "\n"; - dbgs() << "Problematic block: \n" << *PN->getParent() << "\n"; - } Assert(PN->getNumIncomingValues() == Preds.size(), "PHINode should have one entry for each predecessor of its " "parent basic block!", @@ -3358,9 +3354,6 @@ void Verifier::verifyDominatesUse(Instruction &I, unsigned i) { } const Use &U = I.getOperandUse(i); - if (!(InstsInThisBlock.count(Op) || DT.dominates(Op, U))) { - dbgs() << "Problematic function: \n" << *I.getParent()->getParent() << "\n"; - } Assert(InstsInThisBlock.count(Op) || DT.dominates(Op, U), "Instruction does not dominate all uses!", Op, &I); } diff --git a/lib/Target/AArch64/AArch64TargetMachine.cpp b/lib/Target/AArch64/AArch64TargetMachine.cpp index 8cc3ff22725..c52c5544fc7 100644 --- a/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -216,9 +216,6 @@ void AArch64PassConfig::addIRPasses() { // Always expand atomic operations, we don't deal with atomicrmw or cmpxchg // ourselves. addPass(createAtomicExpandPass(TM)); - // XXX-update: Immediate add -licm pass after atomic expand pass to deal with - // loop invariants introduced mannually. -// addPass(createLICMPass()); // Cmpxchg instructions are often used with a subsequent comparison to // determine whether it succeeded. We can exploit existing control-flow in