Mercurial > hg > CbC > CbC_llvm
diff lib/IR/Instruction.cpp @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | c2174574ed3a |
children |
line wrap: on
line diff
--- a/lib/IR/Instruction.cpp Sun Dec 23 19:23:36 2018 +0900 +++ b/lib/IR/Instruction.cpp Wed Aug 14 19:46:37 2019 +0900 @@ -1,9 +1,8 @@ //===-- Instruction.cpp - Implement the Instruction class -----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -12,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/Instruction.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/ADT/DenseSet.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" @@ -138,8 +138,10 @@ cast<GetElementPtrInst>(this)->setIsInBounds(false); break; } + // TODO: FastMathFlags! } + bool Instruction::isExact() const { return cast<PossiblyExactOperator>(this)->isExact(); } @@ -301,6 +303,10 @@ case CatchRet: return "catchret"; case CatchPad: return "catchpad"; case CatchSwitch: return "catchswitch"; + case CallBr: return "callbr"; + + // Standard unary operators... + case FNeg: return "fneg"; // Standard binary operators... case Add: return "add"; @@ -402,6 +408,10 @@ return CI->getCallingConv() == cast<InvokeInst>(I2)->getCallingConv() && CI->getAttributes() == cast<InvokeInst>(I2)->getAttributes() && CI->hasIdenticalOperandBundleSchema(*cast<InvokeInst>(I2)); + if (const CallBrInst *CI = dyn_cast<CallBrInst>(I1)) + return CI->getCallingConv() == cast<CallBrInst>(I2)->getCallingConv() && + CI->getAttributes() == cast<CallBrInst>(I2)->getAttributes() && + CI->hasIdenticalOperandBundleSchema(*cast<CallBrInst>(I2)); if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(I1)) return IVI->getIndices() == cast<InsertValueInst>(I2)->getIndices(); if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(I1)) @@ -512,9 +522,9 @@ case Instruction::CatchRet: return true; case Instruction::Call: - return !cast<CallInst>(this)->doesNotAccessMemory(); case Instruction::Invoke: - return !cast<InvokeInst>(this)->doesNotAccessMemory(); + case Instruction::CallBr: + return !cast<CallBase>(this)->doesNotAccessMemory(); case Instruction::Store: return !cast<StoreInst>(this)->isUnordered(); } @@ -532,9 +542,9 @@ case Instruction::CatchRet: return true; case Instruction::Call: - return !cast<CallInst>(this)->onlyReadsMemory(); case Instruction::Invoke: - return !cast<InvokeInst>(this)->onlyReadsMemory(); + case Instruction::CallBr: + return !cast<CallBase>(this)->onlyReadsMemory(); case Instruction::Load: return !cast<LoadInst>(this)->isUnordered(); } @@ -591,7 +601,29 @@ bool Instruction::isSafeToRemove() const { return (!isa<CallInst>(this) || !this->mayHaveSideEffects()) && - !isa<TerminatorInst>(this); + !this->isTerminator(); +} + +bool Instruction::isLifetimeStartOrEnd() const { + auto II = dyn_cast<IntrinsicInst>(this); + if (!II) + return false; + Intrinsic::ID ID = II->getIntrinsicID(); + return ID == Intrinsic::lifetime_start || ID == Intrinsic::lifetime_end; +} + +const Instruction *Instruction::getNextNonDebugInstruction() const { + for (const Instruction *I = getNextNode(); I; I = I->getNextNode()) + if (!isa<DbgInfoIntrinsic>(I)) + return I; + return nullptr; +} + +const Instruction *Instruction::getPrevNonDebugInstruction() const { + for (const Instruction *I = getPrevNode(); I; I = I->getPrevNode()) + if (!isa<DbgInfoIntrinsic>(I)) + return I; + return nullptr; } bool Instruction::isAssociative() const { @@ -602,12 +634,56 @@ switch (Opcode) { case FMul: case FAdd: - return cast<FPMathOperator>(this)->isFast(); + return cast<FPMathOperator>(this)->hasAllowReassoc() && + cast<FPMathOperator>(this)->hasNoSignedZeros(); default: return false; } } +unsigned Instruction::getNumSuccessors() const { + switch (getOpcode()) { +#define HANDLE_TERM_INST(N, OPC, CLASS) \ + case Instruction::OPC: \ + return static_cast<const CLASS *>(this)->getNumSuccessors(); +#include "llvm/IR/Instruction.def" + default: + break; + } + llvm_unreachable("not a terminator"); +} + +BasicBlock *Instruction::getSuccessor(unsigned idx) const { + switch (getOpcode()) { +#define HANDLE_TERM_INST(N, OPC, CLASS) \ + case Instruction::OPC: \ + return static_cast<const CLASS *>(this)->getSuccessor(idx); +#include "llvm/IR/Instruction.def" + default: + break; + } + llvm_unreachable("not a terminator"); +} + +void Instruction::setSuccessor(unsigned idx, BasicBlock *B) { + switch (getOpcode()) { +#define HANDLE_TERM_INST(N, OPC, CLASS) \ + case Instruction::OPC: \ + return static_cast<CLASS *>(this)->setSuccessor(idx, B); +#include "llvm/IR/Instruction.def" + default: + break; + } + llvm_unreachable("not a terminator"); +} + +void Instruction::replaceSuccessorWith(BasicBlock *OldBB, BasicBlock *NewBB) { + for (unsigned Idx = 0, NumSuccessors = Instruction::getNumSuccessors(); + Idx != NumSuccessors; ++Idx) + if (getSuccessor(Idx) == OldBB) + setSuccessor(Idx, NewBB); +} + Instruction *Instruction::cloneImpl() const { llvm_unreachable("Subclass of Instruction failed to implement cloneImpl"); } @@ -668,52 +744,9 @@ return New; } -void Instruction::updateProfWeight(uint64_t S, uint64_t T) { - auto *ProfileData = getMetadata(LLVMContext::MD_prof); - if (ProfileData == nullptr) - return; - - auto *ProfDataName = dyn_cast<MDString>(ProfileData->getOperand(0)); - if (!ProfDataName || (!ProfDataName->getString().equals("branch_weights") && - !ProfDataName->getString().equals("VP"))) - return; - - MDBuilder MDB(getContext()); - SmallVector<Metadata *, 3> Vals; - Vals.push_back(ProfileData->getOperand(0)); - APInt APS(128, S), APT(128, T); - if (ProfDataName->getString().equals("branch_weights")) - for (unsigned i = 1; i < ProfileData->getNumOperands(); i++) { - // Using APInt::div may be expensive, but most cases should fit 64 bits. - APInt Val(128, - mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(i)) - ->getValue() - .getZExtValue()); - Val *= APS; - Vals.push_back(MDB.createConstant( - ConstantInt::get(Type::getInt64Ty(getContext()), - Val.udiv(APT).getLimitedValue()))); - } - else if (ProfDataName->getString().equals("VP")) - for (unsigned i = 1; i < ProfileData->getNumOperands(); i += 2) { - // The first value is the key of the value profile, which will not change. - Vals.push_back(ProfileData->getOperand(i)); - // Using APInt::div may be expensive, but most cases should fit 64 bits. - APInt Val(128, - mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(i + 1)) - ->getValue() - .getZExtValue()); - Val *= APS; - Vals.push_back(MDB.createConstant( - ConstantInt::get(Type::getInt64Ty(getContext()), - Val.udiv(APT).getLimitedValue()))); - } - setMetadata(LLVMContext::MD_prof, MDNode::get(getContext(), Vals)); -} - void Instruction::setProfWeight(uint64_t W) { - assert((isa<CallInst>(this) || isa<InvokeInst>(this)) && - "Can only set weights for call and invoke instrucitons"); + assert(isa<CallBase>(this) && + "Can only set weights for call like instructions"); SmallVector<uint32_t, 1> Weights; Weights.push_back(W); MDBuilder MDB(getContext());