10b57cec5SDimitry Andric //===- Instructions.cpp - Implement the LLVM instructions -----------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements all of the non-inline methods for the LLVM instruction
100b57cec5SDimitry Andric // classes.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
150b57cec5SDimitry Andric #include "LLVMContextImpl.h"
16bdd1243dSDimitry Andric #include "llvm/ADT/SmallBitVector.h"
170b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
180b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
190b57cec5SDimitry Andric #include "llvm/IR/Attributes.h"
200b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
210b57cec5SDimitry Andric #include "llvm/IR/Constant.h"
22*0fca6ea1SDimitry Andric #include "llvm/IR/ConstantRange.h"
230b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
240b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
250b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
260b57cec5SDimitry Andric #include "llvm/IR/Function.h"
270b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h"
280b57cec5SDimitry Andric #include "llvm/IR/Instruction.h"
290b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
300b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
310b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h"
320b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
330b57cec5SDimitry Andric #include "llvm/IR/Module.h"
340b57cec5SDimitry Andric #include "llvm/IR/Operator.h"
35bdd1243dSDimitry Andric #include "llvm/IR/ProfDataUtils.h"
360b57cec5SDimitry Andric #include "llvm/IR/Type.h"
370b57cec5SDimitry Andric #include "llvm/IR/Value.h"
380b57cec5SDimitry Andric #include "llvm/Support/AtomicOrdering.h"
390b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
40*0fca6ea1SDimitry Andric #include "llvm/Support/CheckedArithmetic.h"
410b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
420b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
43bdd1243dSDimitry Andric #include "llvm/Support/ModRef.h"
448bcb0991SDimitry Andric #include "llvm/Support/TypeSize.h"
450b57cec5SDimitry Andric #include <algorithm>
460b57cec5SDimitry Andric #include <cassert>
470b57cec5SDimitry Andric #include <cstdint>
48bdd1243dSDimitry Andric #include <optional>
490b57cec5SDimitry Andric #include <vector>
500b57cec5SDimitry Andric
510b57cec5SDimitry Andric using namespace llvm;
520b57cec5SDimitry Andric
53fe6060f1SDimitry Andric static cl::opt<bool> DisableI2pP2iOpt(
54fe6060f1SDimitry Andric "disable-i2p-p2i-opt", cl::init(false),
55fe6060f1SDimitry Andric cl::desc("Disables inttoptr/ptrtoint roundtrip optimization"));
56fe6060f1SDimitry Andric
570b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
580b57cec5SDimitry Andric // AllocaInst Class
590b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
600b57cec5SDimitry Andric
61bdd1243dSDimitry Andric std::optional<TypeSize>
getAllocationSize(const DataLayout & DL) const62bdd1243dSDimitry Andric AllocaInst::getAllocationSize(const DataLayout &DL) const {
63bdd1243dSDimitry Andric TypeSize Size = DL.getTypeAllocSize(getAllocatedType());
640b57cec5SDimitry Andric if (isArrayAllocation()) {
655ffd83dbSDimitry Andric auto *C = dyn_cast<ConstantInt>(getArraySize());
660b57cec5SDimitry Andric if (!C)
67bdd1243dSDimitry Andric return std::nullopt;
68e8d8bef9SDimitry Andric assert(!Size.isScalable() && "Array elements cannot have a scalable size");
69*0fca6ea1SDimitry Andric auto CheckedProd =
70*0fca6ea1SDimitry Andric checkedMulUnsigned(Size.getKnownMinValue(), C->getZExtValue());
71*0fca6ea1SDimitry Andric if (!CheckedProd)
72*0fca6ea1SDimitry Andric return std::nullopt;
73*0fca6ea1SDimitry Andric return TypeSize::getFixed(*CheckedProd);
740b57cec5SDimitry Andric }
750b57cec5SDimitry Andric return Size;
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric
78bdd1243dSDimitry Andric std::optional<TypeSize>
getAllocationSizeInBits(const DataLayout & DL) const79bdd1243dSDimitry Andric AllocaInst::getAllocationSizeInBits(const DataLayout &DL) const {
80bdd1243dSDimitry Andric std::optional<TypeSize> Size = getAllocationSize(DL);
81*0fca6ea1SDimitry Andric if (!Size)
82bdd1243dSDimitry Andric return std::nullopt;
83*0fca6ea1SDimitry Andric auto CheckedProd = checkedMulUnsigned(Size->getKnownMinValue(),
84*0fca6ea1SDimitry Andric static_cast<TypeSize::ScalarTy>(8));
85*0fca6ea1SDimitry Andric if (!CheckedProd)
86*0fca6ea1SDimitry Andric return std::nullopt;
87*0fca6ea1SDimitry Andric return TypeSize::get(*CheckedProd, Size->isScalable());
88bdd1243dSDimitry Andric }
89bdd1243dSDimitry Andric
900b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
910b57cec5SDimitry Andric // SelectInst Class
920b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
930b57cec5SDimitry Andric
940b57cec5SDimitry Andric /// areInvalidOperands - Return a string if the specified operands are invalid
950b57cec5SDimitry Andric /// for a select operation, otherwise return null.
areInvalidOperands(Value * Op0,Value * Op1,Value * Op2)960b57cec5SDimitry Andric const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) {
970b57cec5SDimitry Andric if (Op1->getType() != Op2->getType())
980b57cec5SDimitry Andric return "both values to select must have same type";
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric if (Op1->getType()->isTokenTy())
1010b57cec5SDimitry Andric return "select values cannot have token type";
1020b57cec5SDimitry Andric
1030b57cec5SDimitry Andric if (VectorType *VT = dyn_cast<VectorType>(Op0->getType())) {
1040b57cec5SDimitry Andric // Vector select.
1050b57cec5SDimitry Andric if (VT->getElementType() != Type::getInt1Ty(Op0->getContext()))
1060b57cec5SDimitry Andric return "vector select condition element type must be i1";
1070b57cec5SDimitry Andric VectorType *ET = dyn_cast<VectorType>(Op1->getType());
1080b57cec5SDimitry Andric if (!ET)
1090b57cec5SDimitry Andric return "selected values for vector select must be vectors";
1105ffd83dbSDimitry Andric if (ET->getElementCount() != VT->getElementCount())
1110b57cec5SDimitry Andric return "vector select requires selected vectors to have "
1120b57cec5SDimitry Andric "the same vector length as select condition";
1130b57cec5SDimitry Andric } else if (Op0->getType() != Type::getInt1Ty(Op0->getContext())) {
1140b57cec5SDimitry Andric return "select condition must be i1 or <n x i1>";
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric return nullptr;
1170b57cec5SDimitry Andric }
1180b57cec5SDimitry Andric
1190b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1200b57cec5SDimitry Andric // PHINode Class
1210b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1220b57cec5SDimitry Andric
PHINode(const PHINode & PN)1230b57cec5SDimitry Andric PHINode::PHINode(const PHINode &PN)
1240b57cec5SDimitry Andric : Instruction(PN.getType(), Instruction::PHI, nullptr, PN.getNumOperands()),
1250b57cec5SDimitry Andric ReservedSpace(PN.getNumOperands()) {
1260b57cec5SDimitry Andric allocHungoffUses(PN.getNumOperands());
1270b57cec5SDimitry Andric std::copy(PN.op_begin(), PN.op_end(), op_begin());
128bdd1243dSDimitry Andric copyIncomingBlocks(make_range(PN.block_begin(), PN.block_end()));
1290b57cec5SDimitry Andric SubclassOptionalData = PN.SubclassOptionalData;
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric
1320b57cec5SDimitry Andric // removeIncomingValue - Remove an incoming value. This is useful if a
1330b57cec5SDimitry Andric // predecessor basic block is deleted.
removeIncomingValue(unsigned Idx,bool DeletePHIIfEmpty)1340b57cec5SDimitry Andric Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) {
1350b57cec5SDimitry Andric Value *Removed = getIncomingValue(Idx);
1360b57cec5SDimitry Andric
1370b57cec5SDimitry Andric // Move everything after this operand down.
1380b57cec5SDimitry Andric //
1390b57cec5SDimitry Andric // FIXME: we could just swap with the end of the list, then erase. However,
1400b57cec5SDimitry Andric // clients might not expect this to happen. The code as it is thrashes the
1410b57cec5SDimitry Andric // use/def lists, which is kinda lame.
1420b57cec5SDimitry Andric std::copy(op_begin() + Idx + 1, op_end(), op_begin() + Idx);
1435f757f3fSDimitry Andric copyIncomingBlocks(drop_begin(blocks(), Idx + 1), Idx);
1440b57cec5SDimitry Andric
1450b57cec5SDimitry Andric // Nuke the last value.
1460b57cec5SDimitry Andric Op<-1>().set(nullptr);
1470b57cec5SDimitry Andric setNumHungOffUseOperands(getNumOperands() - 1);
1480b57cec5SDimitry Andric
1490b57cec5SDimitry Andric // If the PHI node is dead, because it has zero entries, nuke it now.
1500b57cec5SDimitry Andric if (getNumOperands() == 0 && DeletePHIIfEmpty) {
1510b57cec5SDimitry Andric // If anyone is using this PHI, make them use a dummy value instead...
15281ad6265SDimitry Andric replaceAllUsesWith(PoisonValue::get(getType()));
1530b57cec5SDimitry Andric eraseFromParent();
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric return Removed;
1560b57cec5SDimitry Andric }
1570b57cec5SDimitry Andric
removeIncomingValueIf(function_ref<bool (unsigned)> Predicate,bool DeletePHIIfEmpty)1585f757f3fSDimitry Andric void PHINode::removeIncomingValueIf(function_ref<bool(unsigned)> Predicate,
1595f757f3fSDimitry Andric bool DeletePHIIfEmpty) {
1605f757f3fSDimitry Andric SmallDenseSet<unsigned> RemoveIndices;
1615f757f3fSDimitry Andric for (unsigned Idx = 0; Idx < getNumIncomingValues(); ++Idx)
1625f757f3fSDimitry Andric if (Predicate(Idx))
1635f757f3fSDimitry Andric RemoveIndices.insert(Idx);
1645f757f3fSDimitry Andric
1655f757f3fSDimitry Andric if (RemoveIndices.empty())
1665f757f3fSDimitry Andric return;
1675f757f3fSDimitry Andric
1685f757f3fSDimitry Andric // Remove operands.
1695f757f3fSDimitry Andric auto NewOpEnd = remove_if(operands(), [&](Use &U) {
1705f757f3fSDimitry Andric return RemoveIndices.contains(U.getOperandNo());
1715f757f3fSDimitry Andric });
1725f757f3fSDimitry Andric for (Use &U : make_range(NewOpEnd, op_end()))
1735f757f3fSDimitry Andric U.set(nullptr);
1745f757f3fSDimitry Andric
1755f757f3fSDimitry Andric // Remove incoming blocks.
1765f757f3fSDimitry Andric (void)std::remove_if(const_cast<block_iterator>(block_begin()),
1775f757f3fSDimitry Andric const_cast<block_iterator>(block_end()), [&](BasicBlock *&BB) {
1785f757f3fSDimitry Andric return RemoveIndices.contains(&BB - block_begin());
1795f757f3fSDimitry Andric });
1805f757f3fSDimitry Andric
1815f757f3fSDimitry Andric setNumHungOffUseOperands(getNumOperands() - RemoveIndices.size());
1825f757f3fSDimitry Andric
1835f757f3fSDimitry Andric // If the PHI node is dead, because it has zero entries, nuke it now.
1845f757f3fSDimitry Andric if (getNumOperands() == 0 && DeletePHIIfEmpty) {
1855f757f3fSDimitry Andric // If anyone is using this PHI, make them use a dummy value instead...
1865f757f3fSDimitry Andric replaceAllUsesWith(PoisonValue::get(getType()));
1875f757f3fSDimitry Andric eraseFromParent();
1885f757f3fSDimitry Andric }
1895f757f3fSDimitry Andric }
1905f757f3fSDimitry Andric
1910b57cec5SDimitry Andric /// growOperands - grow operands - This grows the operand list in response
1920b57cec5SDimitry Andric /// to a push_back style of operation. This grows the number of ops by 1.5
1930b57cec5SDimitry Andric /// times.
1940b57cec5SDimitry Andric ///
growOperands()1950b57cec5SDimitry Andric void PHINode::growOperands() {
1960b57cec5SDimitry Andric unsigned e = getNumOperands();
1970b57cec5SDimitry Andric unsigned NumOps = e + e / 2;
1980b57cec5SDimitry Andric if (NumOps < 2) NumOps = 2; // 2 op PHI nodes are VERY common.
1990b57cec5SDimitry Andric
2000b57cec5SDimitry Andric ReservedSpace = NumOps;
2010b57cec5SDimitry Andric growHungoffUses(ReservedSpace, /* IsPhi */ true);
2020b57cec5SDimitry Andric }
2030b57cec5SDimitry Andric
2040b57cec5SDimitry Andric /// hasConstantValue - If the specified PHI node always merges together the same
2050b57cec5SDimitry Andric /// value, return the value, otherwise return null.
hasConstantValue() const2060b57cec5SDimitry Andric Value *PHINode::hasConstantValue() const {
2070b57cec5SDimitry Andric // Exploit the fact that phi nodes always have at least one entry.
2080b57cec5SDimitry Andric Value *ConstantValue = getIncomingValue(0);
2090b57cec5SDimitry Andric for (unsigned i = 1, e = getNumIncomingValues(); i != e; ++i)
2100b57cec5SDimitry Andric if (getIncomingValue(i) != ConstantValue && getIncomingValue(i) != this) {
2110b57cec5SDimitry Andric if (ConstantValue != this)
2120b57cec5SDimitry Andric return nullptr; // Incoming values not all the same.
2130b57cec5SDimitry Andric // The case where the first value is this PHI.
2140b57cec5SDimitry Andric ConstantValue = getIncomingValue(i);
2150b57cec5SDimitry Andric }
2160b57cec5SDimitry Andric if (ConstantValue == this)
217*0fca6ea1SDimitry Andric return PoisonValue::get(getType());
2180b57cec5SDimitry Andric return ConstantValue;
2190b57cec5SDimitry Andric }
2200b57cec5SDimitry Andric
2210b57cec5SDimitry Andric /// hasConstantOrUndefValue - Whether the specified PHI node always merges
2220b57cec5SDimitry Andric /// together the same value, assuming that undefs result in the same value as
2230b57cec5SDimitry Andric /// non-undefs.
2240b57cec5SDimitry Andric /// Unlike \ref hasConstantValue, this does not return a value because the
2250b57cec5SDimitry Andric /// unique non-undef incoming value need not dominate the PHI node.
hasConstantOrUndefValue() const2260b57cec5SDimitry Andric bool PHINode::hasConstantOrUndefValue() const {
2270b57cec5SDimitry Andric Value *ConstantValue = nullptr;
2280b57cec5SDimitry Andric for (unsigned i = 0, e = getNumIncomingValues(); i != e; ++i) {
2290b57cec5SDimitry Andric Value *Incoming = getIncomingValue(i);
2300b57cec5SDimitry Andric if (Incoming != this && !isa<UndefValue>(Incoming)) {
2310b57cec5SDimitry Andric if (ConstantValue && ConstantValue != Incoming)
2320b57cec5SDimitry Andric return false;
2330b57cec5SDimitry Andric ConstantValue = Incoming;
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric }
2360b57cec5SDimitry Andric return true;
2370b57cec5SDimitry Andric }
2380b57cec5SDimitry Andric
2390b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2400b57cec5SDimitry Andric // LandingPadInst Implementation
2410b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2420b57cec5SDimitry Andric
LandingPadInst(Type * RetTy,unsigned NumReservedValues,const Twine & NameStr,InsertPosition InsertBefore)2430b57cec5SDimitry Andric LandingPadInst::LandingPadInst(Type *RetTy, unsigned NumReservedValues,
244*0fca6ea1SDimitry Andric const Twine &NameStr,
245*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
2460b57cec5SDimitry Andric : Instruction(RetTy, Instruction::LandingPad, nullptr, 0, InsertBefore) {
2470b57cec5SDimitry Andric init(NumReservedValues, NameStr);
2480b57cec5SDimitry Andric }
2490b57cec5SDimitry Andric
LandingPadInst(const LandingPadInst & LP)2500b57cec5SDimitry Andric LandingPadInst::LandingPadInst(const LandingPadInst &LP)
2510b57cec5SDimitry Andric : Instruction(LP.getType(), Instruction::LandingPad, nullptr,
2520b57cec5SDimitry Andric LP.getNumOperands()),
2530b57cec5SDimitry Andric ReservedSpace(LP.getNumOperands()) {
2540b57cec5SDimitry Andric allocHungoffUses(LP.getNumOperands());
2550b57cec5SDimitry Andric Use *OL = getOperandList();
2560b57cec5SDimitry Andric const Use *InOL = LP.getOperandList();
2570b57cec5SDimitry Andric for (unsigned I = 0, E = ReservedSpace; I != E; ++I)
2580b57cec5SDimitry Andric OL[I] = InOL[I];
2590b57cec5SDimitry Andric
2600b57cec5SDimitry Andric setCleanup(LP.isCleanup());
2610b57cec5SDimitry Andric }
2620b57cec5SDimitry Andric
Create(Type * RetTy,unsigned NumReservedClauses,const Twine & NameStr,InsertPosition InsertBefore)2630b57cec5SDimitry Andric LandingPadInst *LandingPadInst::Create(Type *RetTy, unsigned NumReservedClauses,
2640b57cec5SDimitry Andric const Twine &NameStr,
265*0fca6ea1SDimitry Andric InsertPosition InsertBefore) {
2660b57cec5SDimitry Andric return new LandingPadInst(RetTy, NumReservedClauses, NameStr, InsertBefore);
2670b57cec5SDimitry Andric }
2680b57cec5SDimitry Andric
init(unsigned NumReservedValues,const Twine & NameStr)2690b57cec5SDimitry Andric void LandingPadInst::init(unsigned NumReservedValues, const Twine &NameStr) {
2700b57cec5SDimitry Andric ReservedSpace = NumReservedValues;
2710b57cec5SDimitry Andric setNumHungOffUseOperands(0);
2720b57cec5SDimitry Andric allocHungoffUses(ReservedSpace);
2730b57cec5SDimitry Andric setName(NameStr);
2740b57cec5SDimitry Andric setCleanup(false);
2750b57cec5SDimitry Andric }
2760b57cec5SDimitry Andric
2770b57cec5SDimitry Andric /// growOperands - grow operands - This grows the operand list in response to a
2780b57cec5SDimitry Andric /// push_back style of operation. This grows the number of ops by 2 times.
growOperands(unsigned Size)2790b57cec5SDimitry Andric void LandingPadInst::growOperands(unsigned Size) {
2800b57cec5SDimitry Andric unsigned e = getNumOperands();
2810b57cec5SDimitry Andric if (ReservedSpace >= e + Size) return;
2820b57cec5SDimitry Andric ReservedSpace = (std::max(e, 1U) + Size / 2) * 2;
2830b57cec5SDimitry Andric growHungoffUses(ReservedSpace);
2840b57cec5SDimitry Andric }
2850b57cec5SDimitry Andric
addClause(Constant * Val)2860b57cec5SDimitry Andric void LandingPadInst::addClause(Constant *Val) {
2870b57cec5SDimitry Andric unsigned OpNo = getNumOperands();
2880b57cec5SDimitry Andric growOperands(1);
2890b57cec5SDimitry Andric assert(OpNo < ReservedSpace && "Growing didn't work!");
2900b57cec5SDimitry Andric setNumHungOffUseOperands(getNumOperands() + 1);
2910b57cec5SDimitry Andric getOperandList()[OpNo] = Val;
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric
2940b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2950b57cec5SDimitry Andric // CallBase Implementation
2960b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2970b57cec5SDimitry Andric
Create(CallBase * CB,ArrayRef<OperandBundleDef> Bundles,InsertPosition InsertPt)2985ffd83dbSDimitry Andric CallBase *CallBase::Create(CallBase *CB, ArrayRef<OperandBundleDef> Bundles,
299*0fca6ea1SDimitry Andric InsertPosition InsertPt) {
3005ffd83dbSDimitry Andric switch (CB->getOpcode()) {
3015ffd83dbSDimitry Andric case Instruction::Call:
3025ffd83dbSDimitry Andric return CallInst::Create(cast<CallInst>(CB), Bundles, InsertPt);
3035ffd83dbSDimitry Andric case Instruction::Invoke:
3045ffd83dbSDimitry Andric return InvokeInst::Create(cast<InvokeInst>(CB), Bundles, InsertPt);
3055ffd83dbSDimitry Andric case Instruction::CallBr:
3065ffd83dbSDimitry Andric return CallBrInst::Create(cast<CallBrInst>(CB), Bundles, InsertPt);
3075ffd83dbSDimitry Andric default:
3085ffd83dbSDimitry Andric llvm_unreachable("Unknown CallBase sub-class!");
3095ffd83dbSDimitry Andric }
3105ffd83dbSDimitry Andric }
3115ffd83dbSDimitry Andric
Create(CallBase * CI,OperandBundleDef OpB,InsertPosition InsertPt)312fe6060f1SDimitry Andric CallBase *CallBase::Create(CallBase *CI, OperandBundleDef OpB,
313*0fca6ea1SDimitry Andric InsertPosition InsertPt) {
314fe6060f1SDimitry Andric SmallVector<OperandBundleDef, 2> OpDefs;
315fe6060f1SDimitry Andric for (unsigned i = 0, e = CI->getNumOperandBundles(); i < e; ++i) {
316fe6060f1SDimitry Andric auto ChildOB = CI->getOperandBundleAt(i);
317fe6060f1SDimitry Andric if (ChildOB.getTagName() != OpB.getTag())
318fe6060f1SDimitry Andric OpDefs.emplace_back(ChildOB);
319fe6060f1SDimitry Andric }
320fe6060f1SDimitry Andric OpDefs.emplace_back(OpB);
321fe6060f1SDimitry Andric return CallBase::Create(CI, OpDefs, InsertPt);
322fe6060f1SDimitry Andric }
323fe6060f1SDimitry Andric
getCaller()3240b57cec5SDimitry Andric Function *CallBase::getCaller() { return getParent()->getParent(); }
3250b57cec5SDimitry Andric
getNumSubclassExtraOperandsDynamic() const3260b57cec5SDimitry Andric unsigned CallBase::getNumSubclassExtraOperandsDynamic() const {
3270b57cec5SDimitry Andric assert(getOpcode() == Instruction::CallBr && "Unexpected opcode!");
3280b57cec5SDimitry Andric return cast<CallBrInst>(this)->getNumIndirectDests() + 1;
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric
isIndirectCall() const3310b57cec5SDimitry Andric bool CallBase::isIndirectCall() const {
3325ffd83dbSDimitry Andric const Value *V = getCalledOperand();
3330b57cec5SDimitry Andric if (isa<Function>(V) || isa<Constant>(V))
3340b57cec5SDimitry Andric return false;
3355ffd83dbSDimitry Andric return !isInlineAsm();
3360b57cec5SDimitry Andric }
3370b57cec5SDimitry Andric
3380b57cec5SDimitry Andric /// Tests if this call site must be tail call optimized. Only a CallInst can
3390b57cec5SDimitry Andric /// be tail call optimized.
isMustTailCall() const3400b57cec5SDimitry Andric bool CallBase::isMustTailCall() const {
3410b57cec5SDimitry Andric if (auto *CI = dyn_cast<CallInst>(this))
3420b57cec5SDimitry Andric return CI->isMustTailCall();
3430b57cec5SDimitry Andric return false;
3440b57cec5SDimitry Andric }
3450b57cec5SDimitry Andric
3460b57cec5SDimitry Andric /// Tests if this call site is marked as a tail call.
isTailCall() const3470b57cec5SDimitry Andric bool CallBase::isTailCall() const {
3480b57cec5SDimitry Andric if (auto *CI = dyn_cast<CallInst>(this))
3490b57cec5SDimitry Andric return CI->isTailCall();
3500b57cec5SDimitry Andric return false;
3510b57cec5SDimitry Andric }
3520b57cec5SDimitry Andric
getIntrinsicID() const3530b57cec5SDimitry Andric Intrinsic::ID CallBase::getIntrinsicID() const {
3540b57cec5SDimitry Andric if (auto *F = getCalledFunction())
3550b57cec5SDimitry Andric return F->getIntrinsicID();
3560b57cec5SDimitry Andric return Intrinsic::not_intrinsic;
3570b57cec5SDimitry Andric }
3580b57cec5SDimitry Andric
getRetNoFPClass() const35906c3fb27SDimitry Andric FPClassTest CallBase::getRetNoFPClass() const {
36006c3fb27SDimitry Andric FPClassTest Mask = Attrs.getRetNoFPClass();
36106c3fb27SDimitry Andric
36206c3fb27SDimitry Andric if (const Function *F = getCalledFunction())
36306c3fb27SDimitry Andric Mask |= F->getAttributes().getRetNoFPClass();
36406c3fb27SDimitry Andric return Mask;
36506c3fb27SDimitry Andric }
36606c3fb27SDimitry Andric
getParamNoFPClass(unsigned i) const36706c3fb27SDimitry Andric FPClassTest CallBase::getParamNoFPClass(unsigned i) const {
36806c3fb27SDimitry Andric FPClassTest Mask = Attrs.getParamNoFPClass(i);
36906c3fb27SDimitry Andric
37006c3fb27SDimitry Andric if (const Function *F = getCalledFunction())
37106c3fb27SDimitry Andric Mask |= F->getAttributes().getParamNoFPClass(i);
37206c3fb27SDimitry Andric return Mask;
37306c3fb27SDimitry Andric }
37406c3fb27SDimitry Andric
getRange() const375*0fca6ea1SDimitry Andric std::optional<ConstantRange> CallBase::getRange() const {
376*0fca6ea1SDimitry Andric const Attribute RangeAttr = getRetAttr(llvm::Attribute::Range);
377*0fca6ea1SDimitry Andric if (RangeAttr.isValid())
378*0fca6ea1SDimitry Andric return RangeAttr.getRange();
379*0fca6ea1SDimitry Andric return std::nullopt;
380*0fca6ea1SDimitry Andric }
381*0fca6ea1SDimitry Andric
isReturnNonNull() const3820b57cec5SDimitry Andric bool CallBase::isReturnNonNull() const {
3830b57cec5SDimitry Andric if (hasRetAttr(Attribute::NonNull))
3840b57cec5SDimitry Andric return true;
3850b57cec5SDimitry Andric
386349cc55cSDimitry Andric if (getRetDereferenceableBytes() > 0 &&
387349cc55cSDimitry Andric !NullPointerIsDefined(getCaller(), getType()->getPointerAddressSpace()))
3880b57cec5SDimitry Andric return true;
3890b57cec5SDimitry Andric
3900b57cec5SDimitry Andric return false;
3910b57cec5SDimitry Andric }
3920b57cec5SDimitry Andric
getArgOperandWithAttribute(Attribute::AttrKind Kind) const39381ad6265SDimitry Andric Value *CallBase::getArgOperandWithAttribute(Attribute::AttrKind Kind) const {
3940b57cec5SDimitry Andric unsigned Index;
3950b57cec5SDimitry Andric
39681ad6265SDimitry Andric if (Attrs.hasAttrSomewhere(Kind, &Index))
3970b57cec5SDimitry Andric return getArgOperand(Index - AttributeList::FirstArgIndex);
3980b57cec5SDimitry Andric if (const Function *F = getCalledFunction())
39981ad6265SDimitry Andric if (F->getAttributes().hasAttrSomewhere(Kind, &Index))
4000b57cec5SDimitry Andric return getArgOperand(Index - AttributeList::FirstArgIndex);
4010b57cec5SDimitry Andric
4020b57cec5SDimitry Andric return nullptr;
4030b57cec5SDimitry Andric }
4040b57cec5SDimitry Andric
4050b57cec5SDimitry Andric /// Determine whether the argument or parameter has the given attribute.
paramHasAttr(unsigned ArgNo,Attribute::AttrKind Kind) const4060b57cec5SDimitry Andric bool CallBase::paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
407349cc55cSDimitry Andric assert(ArgNo < arg_size() && "Param index out of bounds!");
4080b57cec5SDimitry Andric
409349cc55cSDimitry Andric if (Attrs.hasParamAttr(ArgNo, Kind))
4100b57cec5SDimitry Andric return true;
411bdd1243dSDimitry Andric
412bdd1243dSDimitry Andric const Function *F = getCalledFunction();
413bdd1243dSDimitry Andric if (!F)
4140b57cec5SDimitry Andric return false;
415bdd1243dSDimitry Andric
416bdd1243dSDimitry Andric if (!F->getAttributes().hasParamAttr(ArgNo, Kind))
417bdd1243dSDimitry Andric return false;
418bdd1243dSDimitry Andric
419bdd1243dSDimitry Andric // Take into account mod/ref by operand bundles.
420bdd1243dSDimitry Andric switch (Kind) {
421bdd1243dSDimitry Andric case Attribute::ReadNone:
422bdd1243dSDimitry Andric return !hasReadingOperandBundles() && !hasClobberingOperandBundles();
423bdd1243dSDimitry Andric case Attribute::ReadOnly:
424bdd1243dSDimitry Andric return !hasClobberingOperandBundles();
425bdd1243dSDimitry Andric case Attribute::WriteOnly:
426bdd1243dSDimitry Andric return !hasReadingOperandBundles();
427bdd1243dSDimitry Andric default:
428bdd1243dSDimitry Andric return true;
429bdd1243dSDimitry Andric }
4300b57cec5SDimitry Andric }
4310b57cec5SDimitry Andric
hasFnAttrOnCalledFunction(Attribute::AttrKind Kind) const4320b57cec5SDimitry Andric bool CallBase::hasFnAttrOnCalledFunction(Attribute::AttrKind Kind) const {
433*0fca6ea1SDimitry Andric if (auto *F = dyn_cast<Function>(getCalledOperand()))
434349cc55cSDimitry Andric return F->getAttributes().hasFnAttr(Kind);
435349cc55cSDimitry Andric
4360b57cec5SDimitry Andric return false;
4370b57cec5SDimitry Andric }
4380b57cec5SDimitry Andric
hasFnAttrOnCalledFunction(StringRef Kind) const4390b57cec5SDimitry Andric bool CallBase::hasFnAttrOnCalledFunction(StringRef Kind) const {
440*0fca6ea1SDimitry Andric if (auto *F = dyn_cast<Function>(getCalledOperand()))
441349cc55cSDimitry Andric return F->getAttributes().hasFnAttr(Kind);
442349cc55cSDimitry Andric
4430b57cec5SDimitry Andric return false;
4440b57cec5SDimitry Andric }
4450b57cec5SDimitry Andric
44681ad6265SDimitry Andric template <typename AK>
getFnAttrOnCalledFunction(AK Kind) const44781ad6265SDimitry Andric Attribute CallBase::getFnAttrOnCalledFunction(AK Kind) const {
448bdd1243dSDimitry Andric if constexpr (std::is_same_v<AK, Attribute::AttrKind>) {
449bdd1243dSDimitry Andric // getMemoryEffects() correctly combines memory effects from the call-site,
450bdd1243dSDimitry Andric // operand bundles and function.
451bdd1243dSDimitry Andric assert(Kind != Attribute::Memory && "Use getMemoryEffects() instead");
452bdd1243dSDimitry Andric }
453bdd1243dSDimitry Andric
454*0fca6ea1SDimitry Andric if (auto *F = dyn_cast<Function>(getCalledOperand()))
45581ad6265SDimitry Andric return F->getAttributes().getFnAttr(Kind);
45681ad6265SDimitry Andric
45781ad6265SDimitry Andric return Attribute();
45881ad6265SDimitry Andric }
45981ad6265SDimitry Andric
46081ad6265SDimitry Andric template Attribute
46181ad6265SDimitry Andric CallBase::getFnAttrOnCalledFunction(Attribute::AttrKind Kind) const;
46281ad6265SDimitry Andric template Attribute CallBase::getFnAttrOnCalledFunction(StringRef Kind) const;
46381ad6265SDimitry Andric
464*0fca6ea1SDimitry Andric template <typename AK>
getParamAttrOnCalledFunction(unsigned ArgNo,AK Kind) const465*0fca6ea1SDimitry Andric Attribute CallBase::getParamAttrOnCalledFunction(unsigned ArgNo,
466*0fca6ea1SDimitry Andric AK Kind) const {
467*0fca6ea1SDimitry Andric Value *V = getCalledOperand();
468*0fca6ea1SDimitry Andric
469*0fca6ea1SDimitry Andric if (auto *F = dyn_cast<Function>(V))
470*0fca6ea1SDimitry Andric return F->getAttributes().getParamAttr(ArgNo, Kind);
471*0fca6ea1SDimitry Andric
472*0fca6ea1SDimitry Andric return Attribute();
473*0fca6ea1SDimitry Andric }
474*0fca6ea1SDimitry Andric template Attribute
475*0fca6ea1SDimitry Andric CallBase::getParamAttrOnCalledFunction(unsigned ArgNo,
476*0fca6ea1SDimitry Andric Attribute::AttrKind Kind) const;
477*0fca6ea1SDimitry Andric template Attribute CallBase::getParamAttrOnCalledFunction(unsigned ArgNo,
478*0fca6ea1SDimitry Andric StringRef Kind) const;
479*0fca6ea1SDimitry Andric
getOperandBundlesAsDefs(SmallVectorImpl<OperandBundleDef> & Defs) const4805ffd83dbSDimitry Andric void CallBase::getOperandBundlesAsDefs(
4815ffd83dbSDimitry Andric SmallVectorImpl<OperandBundleDef> &Defs) const {
4825ffd83dbSDimitry Andric for (unsigned i = 0, e = getNumOperandBundles(); i != e; ++i)
4835ffd83dbSDimitry Andric Defs.emplace_back(getOperandBundleAt(i));
4845ffd83dbSDimitry Andric }
4855ffd83dbSDimitry Andric
4860b57cec5SDimitry Andric CallBase::op_iterator
populateBundleOperandInfos(ArrayRef<OperandBundleDef> Bundles,const unsigned BeginIndex)4870b57cec5SDimitry Andric CallBase::populateBundleOperandInfos(ArrayRef<OperandBundleDef> Bundles,
4880b57cec5SDimitry Andric const unsigned BeginIndex) {
4890b57cec5SDimitry Andric auto It = op_begin() + BeginIndex;
4900b57cec5SDimitry Andric for (auto &B : Bundles)
4910b57cec5SDimitry Andric It = std::copy(B.input_begin(), B.input_end(), It);
4920b57cec5SDimitry Andric
4930b57cec5SDimitry Andric auto *ContextImpl = getContext().pImpl;
4940b57cec5SDimitry Andric auto BI = Bundles.begin();
4950b57cec5SDimitry Andric unsigned CurrentIndex = BeginIndex;
4960b57cec5SDimitry Andric
4970b57cec5SDimitry Andric for (auto &BOI : bundle_op_infos()) {
4980b57cec5SDimitry Andric assert(BI != Bundles.end() && "Incorrect allocation?");
4990b57cec5SDimitry Andric
5000b57cec5SDimitry Andric BOI.Tag = ContextImpl->getOrInsertBundleTag(BI->getTag());
5010b57cec5SDimitry Andric BOI.Begin = CurrentIndex;
5020b57cec5SDimitry Andric BOI.End = CurrentIndex + BI->input_size();
5030b57cec5SDimitry Andric CurrentIndex = BOI.End;
5040b57cec5SDimitry Andric BI++;
5050b57cec5SDimitry Andric }
5060b57cec5SDimitry Andric
5070b57cec5SDimitry Andric assert(BI == Bundles.end() && "Incorrect allocation?");
5080b57cec5SDimitry Andric
5090b57cec5SDimitry Andric return It;
5100b57cec5SDimitry Andric }
5110b57cec5SDimitry Andric
getBundleOpInfoForOperand(unsigned OpIdx)5125ffd83dbSDimitry Andric CallBase::BundleOpInfo &CallBase::getBundleOpInfoForOperand(unsigned OpIdx) {
5135ffd83dbSDimitry Andric /// When there isn't many bundles, we do a simple linear search.
5145ffd83dbSDimitry Andric /// Else fallback to a binary-search that use the fact that bundles usually
5155ffd83dbSDimitry Andric /// have similar number of argument to get faster convergence.
5165ffd83dbSDimitry Andric if (bundle_op_info_end() - bundle_op_info_begin() < 8) {
5175ffd83dbSDimitry Andric for (auto &BOI : bundle_op_infos())
5185ffd83dbSDimitry Andric if (BOI.Begin <= OpIdx && OpIdx < BOI.End)
5195ffd83dbSDimitry Andric return BOI;
5205ffd83dbSDimitry Andric
5215ffd83dbSDimitry Andric llvm_unreachable("Did not find operand bundle for operand!");
5225ffd83dbSDimitry Andric }
5235ffd83dbSDimitry Andric
5245ffd83dbSDimitry Andric assert(OpIdx >= arg_size() && "the Idx is not in the operand bundles");
5255ffd83dbSDimitry Andric assert(bundle_op_info_end() - bundle_op_info_begin() > 0 &&
5265ffd83dbSDimitry Andric OpIdx < std::prev(bundle_op_info_end())->End &&
5275ffd83dbSDimitry Andric "The Idx isn't in the operand bundle");
5285ffd83dbSDimitry Andric
5295ffd83dbSDimitry Andric /// We need a decimal number below and to prevent using floating point numbers
5305ffd83dbSDimitry Andric /// we use an intergal value multiplied by this constant.
5315ffd83dbSDimitry Andric constexpr unsigned NumberScaling = 1024;
5325ffd83dbSDimitry Andric
5335ffd83dbSDimitry Andric bundle_op_iterator Begin = bundle_op_info_begin();
5345ffd83dbSDimitry Andric bundle_op_iterator End = bundle_op_info_end();
535e8d8bef9SDimitry Andric bundle_op_iterator Current = Begin;
5365ffd83dbSDimitry Andric
5375ffd83dbSDimitry Andric while (Begin != End) {
5385ffd83dbSDimitry Andric unsigned ScaledOperandPerBundle =
5395ffd83dbSDimitry Andric NumberScaling * (std::prev(End)->End - Begin->Begin) / (End - Begin);
5405ffd83dbSDimitry Andric Current = Begin + (((OpIdx - Begin->Begin) * NumberScaling) /
5415ffd83dbSDimitry Andric ScaledOperandPerBundle);
5425ffd83dbSDimitry Andric if (Current >= End)
5435ffd83dbSDimitry Andric Current = std::prev(End);
5445ffd83dbSDimitry Andric assert(Current < End && Current >= Begin &&
5455ffd83dbSDimitry Andric "the operand bundle doesn't cover every value in the range");
5465ffd83dbSDimitry Andric if (OpIdx >= Current->Begin && OpIdx < Current->End)
5475ffd83dbSDimitry Andric break;
5485ffd83dbSDimitry Andric if (OpIdx >= Current->End)
5495ffd83dbSDimitry Andric Begin = Current + 1;
5505ffd83dbSDimitry Andric else
5515ffd83dbSDimitry Andric End = Current;
5525ffd83dbSDimitry Andric }
5535ffd83dbSDimitry Andric
5545ffd83dbSDimitry Andric assert(OpIdx >= Current->Begin && OpIdx < Current->End &&
5555ffd83dbSDimitry Andric "the operand bundle doesn't cover every value in the range");
5565ffd83dbSDimitry Andric return *Current;
5575ffd83dbSDimitry Andric }
5585ffd83dbSDimitry Andric
addOperandBundle(CallBase * CB,uint32_t ID,OperandBundleDef OB,InsertPosition InsertPt)559fe6060f1SDimitry Andric CallBase *CallBase::addOperandBundle(CallBase *CB, uint32_t ID,
560fe6060f1SDimitry Andric OperandBundleDef OB,
561*0fca6ea1SDimitry Andric InsertPosition InsertPt) {
562fe6060f1SDimitry Andric if (CB->getOperandBundle(ID))
563fe6060f1SDimitry Andric return CB;
564fe6060f1SDimitry Andric
565fe6060f1SDimitry Andric SmallVector<OperandBundleDef, 1> Bundles;
566fe6060f1SDimitry Andric CB->getOperandBundlesAsDefs(Bundles);
567fe6060f1SDimitry Andric Bundles.push_back(OB);
568fe6060f1SDimitry Andric return Create(CB, Bundles, InsertPt);
569fe6060f1SDimitry Andric }
570fe6060f1SDimitry Andric
removeOperandBundle(CallBase * CB,uint32_t ID,InsertPosition InsertPt)571fe6060f1SDimitry Andric CallBase *CallBase::removeOperandBundle(CallBase *CB, uint32_t ID,
572*0fca6ea1SDimitry Andric InsertPosition InsertPt) {
573fe6060f1SDimitry Andric SmallVector<OperandBundleDef, 1> Bundles;
574fe6060f1SDimitry Andric bool CreateNew = false;
575fe6060f1SDimitry Andric
576fe6060f1SDimitry Andric for (unsigned I = 0, E = CB->getNumOperandBundles(); I != E; ++I) {
577fe6060f1SDimitry Andric auto Bundle = CB->getOperandBundleAt(I);
578fe6060f1SDimitry Andric if (Bundle.getTagID() == ID) {
579fe6060f1SDimitry Andric CreateNew = true;
580fe6060f1SDimitry Andric continue;
581fe6060f1SDimitry Andric }
582fe6060f1SDimitry Andric Bundles.emplace_back(Bundle);
583fe6060f1SDimitry Andric }
584fe6060f1SDimitry Andric
585fe6060f1SDimitry Andric return CreateNew ? Create(CB, Bundles, InsertPt) : CB;
586fe6060f1SDimitry Andric }
587fe6060f1SDimitry Andric
hasReadingOperandBundles() const588fe6060f1SDimitry Andric bool CallBase::hasReadingOperandBundles() const {
589fe6060f1SDimitry Andric // Implementation note: this is a conservative implementation of operand
59081ad6265SDimitry Andric // bundle semantics, where *any* non-assume operand bundle (other than
59181ad6265SDimitry Andric // ptrauth) forces a callsite to be at least readonly.
592bdd1243dSDimitry Andric return hasOperandBundlesOtherThan(
593bdd1243dSDimitry Andric {LLVMContext::OB_ptrauth, LLVMContext::OB_kcfi}) &&
59481ad6265SDimitry Andric getIntrinsicID() != Intrinsic::assume;
595fe6060f1SDimitry Andric }
596fe6060f1SDimitry Andric
hasClobberingOperandBundles() const597bdd1243dSDimitry Andric bool CallBase::hasClobberingOperandBundles() const {
598bdd1243dSDimitry Andric return hasOperandBundlesOtherThan(
599bdd1243dSDimitry Andric {LLVMContext::OB_deopt, LLVMContext::OB_funclet,
600bdd1243dSDimitry Andric LLVMContext::OB_ptrauth, LLVMContext::OB_kcfi}) &&
601bdd1243dSDimitry Andric getIntrinsicID() != Intrinsic::assume;
602bdd1243dSDimitry Andric }
603bdd1243dSDimitry Andric
getMemoryEffects() const604bdd1243dSDimitry Andric MemoryEffects CallBase::getMemoryEffects() const {
605bdd1243dSDimitry Andric MemoryEffects ME = getAttributes().getMemoryEffects();
606bdd1243dSDimitry Andric if (auto *Fn = dyn_cast<Function>(getCalledOperand())) {
607bdd1243dSDimitry Andric MemoryEffects FnME = Fn->getMemoryEffects();
608bdd1243dSDimitry Andric if (hasOperandBundles()) {
609bdd1243dSDimitry Andric // TODO: Add a method to get memory effects for operand bundles instead.
610bdd1243dSDimitry Andric if (hasReadingOperandBundles())
611bdd1243dSDimitry Andric FnME |= MemoryEffects::readOnly();
612bdd1243dSDimitry Andric if (hasClobberingOperandBundles())
613bdd1243dSDimitry Andric FnME |= MemoryEffects::writeOnly();
614bdd1243dSDimitry Andric }
615bdd1243dSDimitry Andric ME &= FnME;
616bdd1243dSDimitry Andric }
617bdd1243dSDimitry Andric return ME;
618bdd1243dSDimitry Andric }
setMemoryEffects(MemoryEffects ME)619bdd1243dSDimitry Andric void CallBase::setMemoryEffects(MemoryEffects ME) {
620bdd1243dSDimitry Andric addFnAttr(Attribute::getWithMemoryEffects(getContext(), ME));
621bdd1243dSDimitry Andric }
622bdd1243dSDimitry Andric
623bdd1243dSDimitry Andric /// Determine if the function does not access memory.
doesNotAccessMemory() const624bdd1243dSDimitry Andric bool CallBase::doesNotAccessMemory() const {
625bdd1243dSDimitry Andric return getMemoryEffects().doesNotAccessMemory();
626bdd1243dSDimitry Andric }
setDoesNotAccessMemory()627bdd1243dSDimitry Andric void CallBase::setDoesNotAccessMemory() {
628bdd1243dSDimitry Andric setMemoryEffects(MemoryEffects::none());
629bdd1243dSDimitry Andric }
630bdd1243dSDimitry Andric
631bdd1243dSDimitry Andric /// Determine if the function does not access or only reads memory.
onlyReadsMemory() const632bdd1243dSDimitry Andric bool CallBase::onlyReadsMemory() const {
633bdd1243dSDimitry Andric return getMemoryEffects().onlyReadsMemory();
634bdd1243dSDimitry Andric }
setOnlyReadsMemory()635bdd1243dSDimitry Andric void CallBase::setOnlyReadsMemory() {
636bdd1243dSDimitry Andric setMemoryEffects(getMemoryEffects() & MemoryEffects::readOnly());
637bdd1243dSDimitry Andric }
638bdd1243dSDimitry Andric
639bdd1243dSDimitry Andric /// Determine if the function does not access or only writes memory.
onlyWritesMemory() const640bdd1243dSDimitry Andric bool CallBase::onlyWritesMemory() const {
641bdd1243dSDimitry Andric return getMemoryEffects().onlyWritesMemory();
642bdd1243dSDimitry Andric }
setOnlyWritesMemory()643bdd1243dSDimitry Andric void CallBase::setOnlyWritesMemory() {
644bdd1243dSDimitry Andric setMemoryEffects(getMemoryEffects() & MemoryEffects::writeOnly());
645bdd1243dSDimitry Andric }
646bdd1243dSDimitry Andric
647bdd1243dSDimitry Andric /// Determine if the call can access memmory only using pointers based
648bdd1243dSDimitry Andric /// on its arguments.
onlyAccessesArgMemory() const649bdd1243dSDimitry Andric bool CallBase::onlyAccessesArgMemory() const {
650bdd1243dSDimitry Andric return getMemoryEffects().onlyAccessesArgPointees();
651bdd1243dSDimitry Andric }
setOnlyAccessesArgMemory()652bdd1243dSDimitry Andric void CallBase::setOnlyAccessesArgMemory() {
653bdd1243dSDimitry Andric setMemoryEffects(getMemoryEffects() & MemoryEffects::argMemOnly());
654bdd1243dSDimitry Andric }
655bdd1243dSDimitry Andric
656bdd1243dSDimitry Andric /// Determine if the function may only access memory that is
657bdd1243dSDimitry Andric /// inaccessible from the IR.
onlyAccessesInaccessibleMemory() const658bdd1243dSDimitry Andric bool CallBase::onlyAccessesInaccessibleMemory() const {
659bdd1243dSDimitry Andric return getMemoryEffects().onlyAccessesInaccessibleMem();
660bdd1243dSDimitry Andric }
setOnlyAccessesInaccessibleMemory()661bdd1243dSDimitry Andric void CallBase::setOnlyAccessesInaccessibleMemory() {
662bdd1243dSDimitry Andric setMemoryEffects(getMemoryEffects() & MemoryEffects::inaccessibleMemOnly());
663bdd1243dSDimitry Andric }
664bdd1243dSDimitry Andric
665bdd1243dSDimitry Andric /// Determine if the function may only access memory that is
666bdd1243dSDimitry Andric /// either inaccessible from the IR or pointed to by its arguments.
onlyAccessesInaccessibleMemOrArgMem() const667bdd1243dSDimitry Andric bool CallBase::onlyAccessesInaccessibleMemOrArgMem() const {
668bdd1243dSDimitry Andric return getMemoryEffects().onlyAccessesInaccessibleOrArgMem();
669bdd1243dSDimitry Andric }
setOnlyAccessesInaccessibleMemOrArgMem()670bdd1243dSDimitry Andric void CallBase::setOnlyAccessesInaccessibleMemOrArgMem() {
671bdd1243dSDimitry Andric setMemoryEffects(getMemoryEffects() &
672bdd1243dSDimitry Andric MemoryEffects::inaccessibleOrArgMemOnly());
673bdd1243dSDimitry Andric }
674bdd1243dSDimitry Andric
6750b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6760b57cec5SDimitry Andric // CallInst Implementation
6770b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6780b57cec5SDimitry Andric
init(FunctionType * FTy,Value * Func,ArrayRef<Value * > Args,ArrayRef<OperandBundleDef> Bundles,const Twine & NameStr)6790b57cec5SDimitry Andric void CallInst::init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
6800b57cec5SDimitry Andric ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr) {
6810b57cec5SDimitry Andric this->FTy = FTy;
6820b57cec5SDimitry Andric assert(getNumOperands() == Args.size() + CountBundleInputs(Bundles) + 1 &&
6830b57cec5SDimitry Andric "NumOperands not set up?");
6840b57cec5SDimitry Andric
6850b57cec5SDimitry Andric #ifndef NDEBUG
6860b57cec5SDimitry Andric assert((Args.size() == FTy->getNumParams() ||
6870b57cec5SDimitry Andric (FTy->isVarArg() && Args.size() > FTy->getNumParams())) &&
6880b57cec5SDimitry Andric "Calling a function with bad signature!");
6890b57cec5SDimitry Andric
6900b57cec5SDimitry Andric for (unsigned i = 0; i != Args.size(); ++i)
6910b57cec5SDimitry Andric assert((i >= FTy->getNumParams() ||
6920b57cec5SDimitry Andric FTy->getParamType(i) == Args[i]->getType()) &&
6930b57cec5SDimitry Andric "Calling a function with a bad signature!");
6940b57cec5SDimitry Andric #endif
6950b57cec5SDimitry Andric
696fe6060f1SDimitry Andric // Set operands in order of their index to match use-list-order
697fe6060f1SDimitry Andric // prediction.
6980b57cec5SDimitry Andric llvm::copy(Args, op_begin());
699fe6060f1SDimitry Andric setCalledOperand(Func);
7000b57cec5SDimitry Andric
7010b57cec5SDimitry Andric auto It = populateBundleOperandInfos(Bundles, Args.size());
7020b57cec5SDimitry Andric (void)It;
7030b57cec5SDimitry Andric assert(It + 1 == op_end() && "Should add up!");
7040b57cec5SDimitry Andric
7050b57cec5SDimitry Andric setName(NameStr);
7060b57cec5SDimitry Andric }
7070b57cec5SDimitry Andric
init(FunctionType * FTy,Value * Func,const Twine & NameStr)7080b57cec5SDimitry Andric void CallInst::init(FunctionType *FTy, Value *Func, const Twine &NameStr) {
7090b57cec5SDimitry Andric this->FTy = FTy;
7100b57cec5SDimitry Andric assert(getNumOperands() == 1 && "NumOperands not set up?");
7110b57cec5SDimitry Andric setCalledOperand(Func);
7120b57cec5SDimitry Andric
7130b57cec5SDimitry Andric assert(FTy->getNumParams() == 0 && "Calling a function with bad signature");
7140b57cec5SDimitry Andric
7150b57cec5SDimitry Andric setName(NameStr);
7160b57cec5SDimitry Andric }
7170b57cec5SDimitry Andric
CallInst(FunctionType * Ty,Value * Func,const Twine & Name,InsertPosition InsertBefore)7180b57cec5SDimitry Andric CallInst::CallInst(FunctionType *Ty, Value *Func, const Twine &Name,
719*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
7200b57cec5SDimitry Andric : CallBase(Ty->getReturnType(), Instruction::Call,
7210b57cec5SDimitry Andric OperandTraits<CallBase>::op_end(this) - 1, 1, InsertBefore) {
7220b57cec5SDimitry Andric init(Ty, Func, Name);
7230b57cec5SDimitry Andric }
7240b57cec5SDimitry Andric
CallInst(const CallInst & CI)7250b57cec5SDimitry Andric CallInst::CallInst(const CallInst &CI)
7260b57cec5SDimitry Andric : CallBase(CI.Attrs, CI.FTy, CI.getType(), Instruction::Call,
7270b57cec5SDimitry Andric OperandTraits<CallBase>::op_end(this) - CI.getNumOperands(),
7280b57cec5SDimitry Andric CI.getNumOperands()) {
7290b57cec5SDimitry Andric setTailCallKind(CI.getTailCallKind());
7300b57cec5SDimitry Andric setCallingConv(CI.getCallingConv());
7310b57cec5SDimitry Andric
7320b57cec5SDimitry Andric std::copy(CI.op_begin(), CI.op_end(), op_begin());
7330b57cec5SDimitry Andric std::copy(CI.bundle_op_info_begin(), CI.bundle_op_info_end(),
7340b57cec5SDimitry Andric bundle_op_info_begin());
7350b57cec5SDimitry Andric SubclassOptionalData = CI.SubclassOptionalData;
7360b57cec5SDimitry Andric }
7370b57cec5SDimitry Andric
Create(CallInst * CI,ArrayRef<OperandBundleDef> OpB,InsertPosition InsertPt)7380b57cec5SDimitry Andric CallInst *CallInst::Create(CallInst *CI, ArrayRef<OperandBundleDef> OpB,
739*0fca6ea1SDimitry Andric InsertPosition InsertPt) {
7400b57cec5SDimitry Andric std::vector<Value *> Args(CI->arg_begin(), CI->arg_end());
7410b57cec5SDimitry Andric
7425ffd83dbSDimitry Andric auto *NewCI = CallInst::Create(CI->getFunctionType(), CI->getCalledOperand(),
7430b57cec5SDimitry Andric Args, OpB, CI->getName(), InsertPt);
7440b57cec5SDimitry Andric NewCI->setTailCallKind(CI->getTailCallKind());
7450b57cec5SDimitry Andric NewCI->setCallingConv(CI->getCallingConv());
7460b57cec5SDimitry Andric NewCI->SubclassOptionalData = CI->SubclassOptionalData;
7470b57cec5SDimitry Andric NewCI->setAttributes(CI->getAttributes());
7480b57cec5SDimitry Andric NewCI->setDebugLoc(CI->getDebugLoc());
7490b57cec5SDimitry Andric return NewCI;
7500b57cec5SDimitry Andric }
7510b57cec5SDimitry Andric
7520b57cec5SDimitry Andric // Update profile weight for call instruction by scaling it using the ratio
7530b57cec5SDimitry Andric // of S/T. The meaning of "branch_weights" meta data for call instruction is
7540b57cec5SDimitry Andric // transfered to represent call count.
updateProfWeight(uint64_t S,uint64_t T)7550b57cec5SDimitry Andric void CallInst::updateProfWeight(uint64_t S, uint64_t T) {
7560b57cec5SDimitry Andric if (T == 0) {
7570b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Attempting to update profile weights will result in "
7580b57cec5SDimitry Andric "div by 0. Ignoring. Likely the function "
7590b57cec5SDimitry Andric << getParent()->getParent()->getName()
7600b57cec5SDimitry Andric << " has 0 entry count, and contains call instructions "
7610b57cec5SDimitry Andric "with non-zero prof info.");
7620b57cec5SDimitry Andric return;
7630b57cec5SDimitry Andric }
764*0fca6ea1SDimitry Andric scaleProfData(*this, S, T);
7650b57cec5SDimitry Andric }
7660b57cec5SDimitry Andric
7670b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7680b57cec5SDimitry Andric // InvokeInst Implementation
7690b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7700b57cec5SDimitry Andric
init(FunctionType * FTy,Value * Fn,BasicBlock * IfNormal,BasicBlock * IfException,ArrayRef<Value * > Args,ArrayRef<OperandBundleDef> Bundles,const Twine & NameStr)7710b57cec5SDimitry Andric void InvokeInst::init(FunctionType *FTy, Value *Fn, BasicBlock *IfNormal,
7720b57cec5SDimitry Andric BasicBlock *IfException, ArrayRef<Value *> Args,
7730b57cec5SDimitry Andric ArrayRef<OperandBundleDef> Bundles,
7740b57cec5SDimitry Andric const Twine &NameStr) {
7750b57cec5SDimitry Andric this->FTy = FTy;
7760b57cec5SDimitry Andric
7770b57cec5SDimitry Andric assert((int)getNumOperands() ==
7780b57cec5SDimitry Andric ComputeNumOperands(Args.size(), CountBundleInputs(Bundles)) &&
7790b57cec5SDimitry Andric "NumOperands not set up?");
7800b57cec5SDimitry Andric
7810b57cec5SDimitry Andric #ifndef NDEBUG
7820b57cec5SDimitry Andric assert(((Args.size() == FTy->getNumParams()) ||
7830b57cec5SDimitry Andric (FTy->isVarArg() && Args.size() > FTy->getNumParams())) &&
7840b57cec5SDimitry Andric "Invoking a function with bad signature");
7850b57cec5SDimitry Andric
7860b57cec5SDimitry Andric for (unsigned i = 0, e = Args.size(); i != e; i++)
7870b57cec5SDimitry Andric assert((i >= FTy->getNumParams() ||
7880b57cec5SDimitry Andric FTy->getParamType(i) == Args[i]->getType()) &&
7890b57cec5SDimitry Andric "Invoking a function with a bad signature!");
7900b57cec5SDimitry Andric #endif
7910b57cec5SDimitry Andric
792fe6060f1SDimitry Andric // Set operands in order of their index to match use-list-order
793fe6060f1SDimitry Andric // prediction.
7940b57cec5SDimitry Andric llvm::copy(Args, op_begin());
795fe6060f1SDimitry Andric setNormalDest(IfNormal);
796fe6060f1SDimitry Andric setUnwindDest(IfException);
797fe6060f1SDimitry Andric setCalledOperand(Fn);
7980b57cec5SDimitry Andric
7990b57cec5SDimitry Andric auto It = populateBundleOperandInfos(Bundles, Args.size());
8000b57cec5SDimitry Andric (void)It;
8010b57cec5SDimitry Andric assert(It + 3 == op_end() && "Should add up!");
8020b57cec5SDimitry Andric
8030b57cec5SDimitry Andric setName(NameStr);
8040b57cec5SDimitry Andric }
8050b57cec5SDimitry Andric
InvokeInst(const InvokeInst & II)8060b57cec5SDimitry Andric InvokeInst::InvokeInst(const InvokeInst &II)
8070b57cec5SDimitry Andric : CallBase(II.Attrs, II.FTy, II.getType(), Instruction::Invoke,
8080b57cec5SDimitry Andric OperandTraits<CallBase>::op_end(this) - II.getNumOperands(),
8090b57cec5SDimitry Andric II.getNumOperands()) {
8100b57cec5SDimitry Andric setCallingConv(II.getCallingConv());
8110b57cec5SDimitry Andric std::copy(II.op_begin(), II.op_end(), op_begin());
8120b57cec5SDimitry Andric std::copy(II.bundle_op_info_begin(), II.bundle_op_info_end(),
8130b57cec5SDimitry Andric bundle_op_info_begin());
8140b57cec5SDimitry Andric SubclassOptionalData = II.SubclassOptionalData;
8150b57cec5SDimitry Andric }
8160b57cec5SDimitry Andric
Create(InvokeInst * II,ArrayRef<OperandBundleDef> OpB,InsertPosition InsertPt)8170b57cec5SDimitry Andric InvokeInst *InvokeInst::Create(InvokeInst *II, ArrayRef<OperandBundleDef> OpB,
818*0fca6ea1SDimitry Andric InsertPosition InsertPt) {
8190b57cec5SDimitry Andric std::vector<Value *> Args(II->arg_begin(), II->arg_end());
8200b57cec5SDimitry Andric
8215ffd83dbSDimitry Andric auto *NewII = InvokeInst::Create(
8225ffd83dbSDimitry Andric II->getFunctionType(), II->getCalledOperand(), II->getNormalDest(),
8235ffd83dbSDimitry Andric II->getUnwindDest(), Args, OpB, II->getName(), InsertPt);
8240b57cec5SDimitry Andric NewII->setCallingConv(II->getCallingConv());
8250b57cec5SDimitry Andric NewII->SubclassOptionalData = II->SubclassOptionalData;
8260b57cec5SDimitry Andric NewII->setAttributes(II->getAttributes());
8270b57cec5SDimitry Andric NewII->setDebugLoc(II->getDebugLoc());
8280b57cec5SDimitry Andric return NewII;
8290b57cec5SDimitry Andric }
8300b57cec5SDimitry Andric
getLandingPadInst() const8310b57cec5SDimitry Andric LandingPadInst *InvokeInst::getLandingPadInst() const {
8320b57cec5SDimitry Andric return cast<LandingPadInst>(getUnwindDest()->getFirstNonPHI());
8330b57cec5SDimitry Andric }
8340b57cec5SDimitry Andric
updateProfWeight(uint64_t S,uint64_t T)835*0fca6ea1SDimitry Andric void InvokeInst::updateProfWeight(uint64_t S, uint64_t T) {
836*0fca6ea1SDimitry Andric if (T == 0) {
837*0fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << "Attempting to update profile weights will result in "
838*0fca6ea1SDimitry Andric "div by 0. Ignoring. Likely the function "
839*0fca6ea1SDimitry Andric << getParent()->getParent()->getName()
840*0fca6ea1SDimitry Andric << " has 0 entry count, and contains call instructions "
841*0fca6ea1SDimitry Andric "with non-zero prof info.");
842*0fca6ea1SDimitry Andric return;
843*0fca6ea1SDimitry Andric }
844*0fca6ea1SDimitry Andric scaleProfData(*this, S, T);
845*0fca6ea1SDimitry Andric }
846*0fca6ea1SDimitry Andric
8470b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8480b57cec5SDimitry Andric // CallBrInst Implementation
8490b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8500b57cec5SDimitry Andric
init(FunctionType * FTy,Value * Fn,BasicBlock * Fallthrough,ArrayRef<BasicBlock * > IndirectDests,ArrayRef<Value * > Args,ArrayRef<OperandBundleDef> Bundles,const Twine & NameStr)8510b57cec5SDimitry Andric void CallBrInst::init(FunctionType *FTy, Value *Fn, BasicBlock *Fallthrough,
8520b57cec5SDimitry Andric ArrayRef<BasicBlock *> IndirectDests,
8530b57cec5SDimitry Andric ArrayRef<Value *> Args,
8540b57cec5SDimitry Andric ArrayRef<OperandBundleDef> Bundles,
8550b57cec5SDimitry Andric const Twine &NameStr) {
8560b57cec5SDimitry Andric this->FTy = FTy;
8570b57cec5SDimitry Andric
8580b57cec5SDimitry Andric assert((int)getNumOperands() ==
8590b57cec5SDimitry Andric ComputeNumOperands(Args.size(), IndirectDests.size(),
8600b57cec5SDimitry Andric CountBundleInputs(Bundles)) &&
8610b57cec5SDimitry Andric "NumOperands not set up?");
8620b57cec5SDimitry Andric
8630b57cec5SDimitry Andric #ifndef NDEBUG
8640b57cec5SDimitry Andric assert(((Args.size() == FTy->getNumParams()) ||
8650b57cec5SDimitry Andric (FTy->isVarArg() && Args.size() > FTy->getNumParams())) &&
8660b57cec5SDimitry Andric "Calling a function with bad signature");
8670b57cec5SDimitry Andric
8680b57cec5SDimitry Andric for (unsigned i = 0, e = Args.size(); i != e; i++)
8690b57cec5SDimitry Andric assert((i >= FTy->getNumParams() ||
8700b57cec5SDimitry Andric FTy->getParamType(i) == Args[i]->getType()) &&
8710b57cec5SDimitry Andric "Calling a function with a bad signature!");
8720b57cec5SDimitry Andric #endif
8730b57cec5SDimitry Andric
874fe6060f1SDimitry Andric // Set operands in order of their index to match use-list-order
875fe6060f1SDimitry Andric // prediction.
8760b57cec5SDimitry Andric std::copy(Args.begin(), Args.end(), op_begin());
877fe6060f1SDimitry Andric NumIndirectDests = IndirectDests.size();
878fe6060f1SDimitry Andric setDefaultDest(Fallthrough);
879fe6060f1SDimitry Andric for (unsigned i = 0; i != NumIndirectDests; ++i)
880fe6060f1SDimitry Andric setIndirectDest(i, IndirectDests[i]);
881fe6060f1SDimitry Andric setCalledOperand(Fn);
8820b57cec5SDimitry Andric
8830b57cec5SDimitry Andric auto It = populateBundleOperandInfos(Bundles, Args.size());
8840b57cec5SDimitry Andric (void)It;
8850b57cec5SDimitry Andric assert(It + 2 + IndirectDests.size() == op_end() && "Should add up!");
8860b57cec5SDimitry Andric
8870b57cec5SDimitry Andric setName(NameStr);
8880b57cec5SDimitry Andric }
8890b57cec5SDimitry Andric
CallBrInst(const CallBrInst & CBI)8900b57cec5SDimitry Andric CallBrInst::CallBrInst(const CallBrInst &CBI)
8910b57cec5SDimitry Andric : CallBase(CBI.Attrs, CBI.FTy, CBI.getType(), Instruction::CallBr,
8920b57cec5SDimitry Andric OperandTraits<CallBase>::op_end(this) - CBI.getNumOperands(),
8930b57cec5SDimitry Andric CBI.getNumOperands()) {
8940b57cec5SDimitry Andric setCallingConv(CBI.getCallingConv());
8950b57cec5SDimitry Andric std::copy(CBI.op_begin(), CBI.op_end(), op_begin());
8960b57cec5SDimitry Andric std::copy(CBI.bundle_op_info_begin(), CBI.bundle_op_info_end(),
8970b57cec5SDimitry Andric bundle_op_info_begin());
8980b57cec5SDimitry Andric SubclassOptionalData = CBI.SubclassOptionalData;
8990b57cec5SDimitry Andric NumIndirectDests = CBI.NumIndirectDests;
9000b57cec5SDimitry Andric }
9010b57cec5SDimitry Andric
Create(CallBrInst * CBI,ArrayRef<OperandBundleDef> OpB,InsertPosition InsertPt)9020b57cec5SDimitry Andric CallBrInst *CallBrInst::Create(CallBrInst *CBI, ArrayRef<OperandBundleDef> OpB,
903*0fca6ea1SDimitry Andric InsertPosition InsertPt) {
9040b57cec5SDimitry Andric std::vector<Value *> Args(CBI->arg_begin(), CBI->arg_end());
9050b57cec5SDimitry Andric
9065ffd83dbSDimitry Andric auto *NewCBI = CallBrInst::Create(
9075ffd83dbSDimitry Andric CBI->getFunctionType(), CBI->getCalledOperand(), CBI->getDefaultDest(),
9085ffd83dbSDimitry Andric CBI->getIndirectDests(), Args, OpB, CBI->getName(), InsertPt);
9090b57cec5SDimitry Andric NewCBI->setCallingConv(CBI->getCallingConv());
9100b57cec5SDimitry Andric NewCBI->SubclassOptionalData = CBI->SubclassOptionalData;
9110b57cec5SDimitry Andric NewCBI->setAttributes(CBI->getAttributes());
9120b57cec5SDimitry Andric NewCBI->setDebugLoc(CBI->getDebugLoc());
9130b57cec5SDimitry Andric NewCBI->NumIndirectDests = CBI->NumIndirectDests;
9140b57cec5SDimitry Andric return NewCBI;
9150b57cec5SDimitry Andric }
9160b57cec5SDimitry Andric
9170b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9180b57cec5SDimitry Andric // ReturnInst Implementation
9190b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9200b57cec5SDimitry Andric
ReturnInst(const ReturnInst & RI)9210b57cec5SDimitry Andric ReturnInst::ReturnInst(const ReturnInst &RI)
9220b57cec5SDimitry Andric : Instruction(Type::getVoidTy(RI.getContext()), Instruction::Ret,
9230b57cec5SDimitry Andric OperandTraits<ReturnInst>::op_end(this) - RI.getNumOperands(),
9240b57cec5SDimitry Andric RI.getNumOperands()) {
9250b57cec5SDimitry Andric if (RI.getNumOperands())
9260b57cec5SDimitry Andric Op<0>() = RI.Op<0>();
9270b57cec5SDimitry Andric SubclassOptionalData = RI.SubclassOptionalData;
9280b57cec5SDimitry Andric }
9290b57cec5SDimitry Andric
ReturnInst(LLVMContext & C,Value * retVal,InsertPosition InsertBefore)930*0fca6ea1SDimitry Andric ReturnInst::ReturnInst(LLVMContext &C, Value *retVal,
931*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
9320b57cec5SDimitry Andric : Instruction(Type::getVoidTy(C), Instruction::Ret,
9330b57cec5SDimitry Andric OperandTraits<ReturnInst>::op_end(this) - !!retVal, !!retVal,
9340b57cec5SDimitry Andric InsertBefore) {
9350b57cec5SDimitry Andric if (retVal)
9360b57cec5SDimitry Andric Op<0>() = retVal;
9370b57cec5SDimitry Andric }
9380b57cec5SDimitry Andric
9390b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9400b57cec5SDimitry Andric // ResumeInst Implementation
9410b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9420b57cec5SDimitry Andric
ResumeInst(const ResumeInst & RI)9430b57cec5SDimitry Andric ResumeInst::ResumeInst(const ResumeInst &RI)
9440b57cec5SDimitry Andric : Instruction(Type::getVoidTy(RI.getContext()), Instruction::Resume,
9450b57cec5SDimitry Andric OperandTraits<ResumeInst>::op_begin(this), 1) {
9460b57cec5SDimitry Andric Op<0>() = RI.Op<0>();
9470b57cec5SDimitry Andric }
9480b57cec5SDimitry Andric
ResumeInst(Value * Exn,InsertPosition InsertBefore)949*0fca6ea1SDimitry Andric ResumeInst::ResumeInst(Value *Exn, InsertPosition InsertBefore)
9500b57cec5SDimitry Andric : Instruction(Type::getVoidTy(Exn->getContext()), Instruction::Resume,
9510b57cec5SDimitry Andric OperandTraits<ResumeInst>::op_begin(this), 1, InsertBefore) {
9520b57cec5SDimitry Andric Op<0>() = Exn;
9530b57cec5SDimitry Andric }
9540b57cec5SDimitry Andric
9550b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9560b57cec5SDimitry Andric // CleanupReturnInst Implementation
9570b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9580b57cec5SDimitry Andric
CleanupReturnInst(const CleanupReturnInst & CRI)9590b57cec5SDimitry Andric CleanupReturnInst::CleanupReturnInst(const CleanupReturnInst &CRI)
9600b57cec5SDimitry Andric : Instruction(CRI.getType(), Instruction::CleanupRet,
9610b57cec5SDimitry Andric OperandTraits<CleanupReturnInst>::op_end(this) -
9620b57cec5SDimitry Andric CRI.getNumOperands(),
9630b57cec5SDimitry Andric CRI.getNumOperands()) {
9645ffd83dbSDimitry Andric setSubclassData<Instruction::OpaqueField>(
9655ffd83dbSDimitry Andric CRI.getSubclassData<Instruction::OpaqueField>());
9660b57cec5SDimitry Andric Op<0>() = CRI.Op<0>();
9670b57cec5SDimitry Andric if (CRI.hasUnwindDest())
9680b57cec5SDimitry Andric Op<1>() = CRI.Op<1>();
9690b57cec5SDimitry Andric }
9700b57cec5SDimitry Andric
init(Value * CleanupPad,BasicBlock * UnwindBB)9710b57cec5SDimitry Andric void CleanupReturnInst::init(Value *CleanupPad, BasicBlock *UnwindBB) {
9720b57cec5SDimitry Andric if (UnwindBB)
9735ffd83dbSDimitry Andric setSubclassData<UnwindDestField>(true);
9740b57cec5SDimitry Andric
9750b57cec5SDimitry Andric Op<0>() = CleanupPad;
9760b57cec5SDimitry Andric if (UnwindBB)
9770b57cec5SDimitry Andric Op<1>() = UnwindBB;
9780b57cec5SDimitry Andric }
9790b57cec5SDimitry Andric
CleanupReturnInst(Value * CleanupPad,BasicBlock * UnwindBB,unsigned Values,InsertPosition InsertBefore)9800b57cec5SDimitry Andric CleanupReturnInst::CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB,
981*0fca6ea1SDimitry Andric unsigned Values,
982*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
9830b57cec5SDimitry Andric : Instruction(Type::getVoidTy(CleanupPad->getContext()),
9840b57cec5SDimitry Andric Instruction::CleanupRet,
9850b57cec5SDimitry Andric OperandTraits<CleanupReturnInst>::op_end(this) - Values,
9860b57cec5SDimitry Andric Values, InsertBefore) {
9870b57cec5SDimitry Andric init(CleanupPad, UnwindBB);
9880b57cec5SDimitry Andric }
9890b57cec5SDimitry Andric
9900b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9910b57cec5SDimitry Andric // CatchReturnInst Implementation
9920b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
init(Value * CatchPad,BasicBlock * BB)9930b57cec5SDimitry Andric void CatchReturnInst::init(Value *CatchPad, BasicBlock *BB) {
9940b57cec5SDimitry Andric Op<0>() = CatchPad;
9950b57cec5SDimitry Andric Op<1>() = BB;
9960b57cec5SDimitry Andric }
9970b57cec5SDimitry Andric
CatchReturnInst(const CatchReturnInst & CRI)9980b57cec5SDimitry Andric CatchReturnInst::CatchReturnInst(const CatchReturnInst &CRI)
9990b57cec5SDimitry Andric : Instruction(Type::getVoidTy(CRI.getContext()), Instruction::CatchRet,
10000b57cec5SDimitry Andric OperandTraits<CatchReturnInst>::op_begin(this), 2) {
10010b57cec5SDimitry Andric Op<0>() = CRI.Op<0>();
10020b57cec5SDimitry Andric Op<1>() = CRI.Op<1>();
10030b57cec5SDimitry Andric }
10040b57cec5SDimitry Andric
CatchReturnInst(Value * CatchPad,BasicBlock * BB,InsertPosition InsertBefore)10050b57cec5SDimitry Andric CatchReturnInst::CatchReturnInst(Value *CatchPad, BasicBlock *BB,
1006*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
10070b57cec5SDimitry Andric : Instruction(Type::getVoidTy(BB->getContext()), Instruction::CatchRet,
10080b57cec5SDimitry Andric OperandTraits<CatchReturnInst>::op_begin(this), 2,
10090b57cec5SDimitry Andric InsertBefore) {
10100b57cec5SDimitry Andric init(CatchPad, BB);
10110b57cec5SDimitry Andric }
10120b57cec5SDimitry Andric
10130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
10140b57cec5SDimitry Andric // CatchSwitchInst Implementation
10150b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
10160b57cec5SDimitry Andric
CatchSwitchInst(Value * ParentPad,BasicBlock * UnwindDest,unsigned NumReservedValues,const Twine & NameStr,InsertPosition InsertBefore)10170b57cec5SDimitry Andric CatchSwitchInst::CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest,
10180b57cec5SDimitry Andric unsigned NumReservedValues,
10190b57cec5SDimitry Andric const Twine &NameStr,
1020*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
10210b57cec5SDimitry Andric : Instruction(ParentPad->getType(), Instruction::CatchSwitch, nullptr, 0,
10220b57cec5SDimitry Andric InsertBefore) {
10230b57cec5SDimitry Andric if (UnwindDest)
10240b57cec5SDimitry Andric ++NumReservedValues;
10250b57cec5SDimitry Andric init(ParentPad, UnwindDest, NumReservedValues + 1);
10260b57cec5SDimitry Andric setName(NameStr);
10270b57cec5SDimitry Andric }
10280b57cec5SDimitry Andric
CatchSwitchInst(const CatchSwitchInst & CSI)10290b57cec5SDimitry Andric CatchSwitchInst::CatchSwitchInst(const CatchSwitchInst &CSI)
10300b57cec5SDimitry Andric : Instruction(CSI.getType(), Instruction::CatchSwitch, nullptr,
10310b57cec5SDimitry Andric CSI.getNumOperands()) {
10320b57cec5SDimitry Andric init(CSI.getParentPad(), CSI.getUnwindDest(), CSI.getNumOperands());
10330b57cec5SDimitry Andric setNumHungOffUseOperands(ReservedSpace);
10340b57cec5SDimitry Andric Use *OL = getOperandList();
10350b57cec5SDimitry Andric const Use *InOL = CSI.getOperandList();
10360b57cec5SDimitry Andric for (unsigned I = 1, E = ReservedSpace; I != E; ++I)
10370b57cec5SDimitry Andric OL[I] = InOL[I];
10380b57cec5SDimitry Andric }
10390b57cec5SDimitry Andric
init(Value * ParentPad,BasicBlock * UnwindDest,unsigned NumReservedValues)10400b57cec5SDimitry Andric void CatchSwitchInst::init(Value *ParentPad, BasicBlock *UnwindDest,
10410b57cec5SDimitry Andric unsigned NumReservedValues) {
10420b57cec5SDimitry Andric assert(ParentPad && NumReservedValues);
10430b57cec5SDimitry Andric
10440b57cec5SDimitry Andric ReservedSpace = NumReservedValues;
10450b57cec5SDimitry Andric setNumHungOffUseOperands(UnwindDest ? 2 : 1);
10460b57cec5SDimitry Andric allocHungoffUses(ReservedSpace);
10470b57cec5SDimitry Andric
10480b57cec5SDimitry Andric Op<0>() = ParentPad;
10490b57cec5SDimitry Andric if (UnwindDest) {
10505ffd83dbSDimitry Andric setSubclassData<UnwindDestField>(true);
10510b57cec5SDimitry Andric setUnwindDest(UnwindDest);
10520b57cec5SDimitry Andric }
10530b57cec5SDimitry Andric }
10540b57cec5SDimitry Andric
10550b57cec5SDimitry Andric /// growOperands - grow operands - This grows the operand list in response to a
10560b57cec5SDimitry Andric /// push_back style of operation. This grows the number of ops by 2 times.
growOperands(unsigned Size)10570b57cec5SDimitry Andric void CatchSwitchInst::growOperands(unsigned Size) {
10580b57cec5SDimitry Andric unsigned NumOperands = getNumOperands();
10590b57cec5SDimitry Andric assert(NumOperands >= 1);
10600b57cec5SDimitry Andric if (ReservedSpace >= NumOperands + Size)
10610b57cec5SDimitry Andric return;
10620b57cec5SDimitry Andric ReservedSpace = (NumOperands + Size / 2) * 2;
10630b57cec5SDimitry Andric growHungoffUses(ReservedSpace);
10640b57cec5SDimitry Andric }
10650b57cec5SDimitry Andric
addHandler(BasicBlock * Handler)10660b57cec5SDimitry Andric void CatchSwitchInst::addHandler(BasicBlock *Handler) {
10670b57cec5SDimitry Andric unsigned OpNo = getNumOperands();
10680b57cec5SDimitry Andric growOperands(1);
10690b57cec5SDimitry Andric assert(OpNo < ReservedSpace && "Growing didn't work!");
10700b57cec5SDimitry Andric setNumHungOffUseOperands(getNumOperands() + 1);
10710b57cec5SDimitry Andric getOperandList()[OpNo] = Handler;
10720b57cec5SDimitry Andric }
10730b57cec5SDimitry Andric
removeHandler(handler_iterator HI)10740b57cec5SDimitry Andric void CatchSwitchInst::removeHandler(handler_iterator HI) {
10750b57cec5SDimitry Andric // Move all subsequent handlers up one.
10760b57cec5SDimitry Andric Use *EndDst = op_end() - 1;
10770b57cec5SDimitry Andric for (Use *CurDst = HI.getCurrent(); CurDst != EndDst; ++CurDst)
10780b57cec5SDimitry Andric *CurDst = *(CurDst + 1);
10790b57cec5SDimitry Andric // Null out the last handler use.
10800b57cec5SDimitry Andric *EndDst = nullptr;
10810b57cec5SDimitry Andric
10820b57cec5SDimitry Andric setNumHungOffUseOperands(getNumOperands() - 1);
10830b57cec5SDimitry Andric }
10840b57cec5SDimitry Andric
10850b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
10860b57cec5SDimitry Andric // FuncletPadInst Implementation
10870b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
init(Value * ParentPad,ArrayRef<Value * > Args,const Twine & NameStr)10880b57cec5SDimitry Andric void FuncletPadInst::init(Value *ParentPad, ArrayRef<Value *> Args,
10890b57cec5SDimitry Andric const Twine &NameStr) {
10900b57cec5SDimitry Andric assert(getNumOperands() == 1 + Args.size() && "NumOperands not set up?");
10910b57cec5SDimitry Andric llvm::copy(Args, op_begin());
10920b57cec5SDimitry Andric setParentPad(ParentPad);
10930b57cec5SDimitry Andric setName(NameStr);
10940b57cec5SDimitry Andric }
10950b57cec5SDimitry Andric
FuncletPadInst(const FuncletPadInst & FPI)10960b57cec5SDimitry Andric FuncletPadInst::FuncletPadInst(const FuncletPadInst &FPI)
10970b57cec5SDimitry Andric : Instruction(FPI.getType(), FPI.getOpcode(),
10980b57cec5SDimitry Andric OperandTraits<FuncletPadInst>::op_end(this) -
10990b57cec5SDimitry Andric FPI.getNumOperands(),
11000b57cec5SDimitry Andric FPI.getNumOperands()) {
11010b57cec5SDimitry Andric std::copy(FPI.op_begin(), FPI.op_end(), op_begin());
11020b57cec5SDimitry Andric setParentPad(FPI.getParentPad());
11030b57cec5SDimitry Andric }
11040b57cec5SDimitry Andric
FuncletPadInst(Instruction::FuncletPadOps Op,Value * ParentPad,ArrayRef<Value * > Args,unsigned Values,const Twine & NameStr,InsertPosition InsertBefore)11050b57cec5SDimitry Andric FuncletPadInst::FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad,
11060b57cec5SDimitry Andric ArrayRef<Value *> Args, unsigned Values,
1107*0fca6ea1SDimitry Andric const Twine &NameStr,
1108*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
11090b57cec5SDimitry Andric : Instruction(ParentPad->getType(), Op,
11100b57cec5SDimitry Andric OperandTraits<FuncletPadInst>::op_end(this) - Values, Values,
11110b57cec5SDimitry Andric InsertBefore) {
11120b57cec5SDimitry Andric init(ParentPad, Args, NameStr);
11130b57cec5SDimitry Andric }
11140b57cec5SDimitry Andric
11150b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11160b57cec5SDimitry Andric // UnreachableInst Implementation
11170b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11180b57cec5SDimitry Andric
UnreachableInst(LLVMContext & Context,InsertPosition InsertBefore)11190b57cec5SDimitry Andric UnreachableInst::UnreachableInst(LLVMContext &Context,
1120*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
11210b57cec5SDimitry Andric : Instruction(Type::getVoidTy(Context), Instruction::Unreachable, nullptr,
11220b57cec5SDimitry Andric 0, InsertBefore) {}
11230b57cec5SDimitry Andric
11240b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11250b57cec5SDimitry Andric // BranchInst Implementation
11260b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11270b57cec5SDimitry Andric
AssertOK()11280b57cec5SDimitry Andric void BranchInst::AssertOK() {
11290b57cec5SDimitry Andric if (isConditional())
11300b57cec5SDimitry Andric assert(getCondition()->getType()->isIntegerTy(1) &&
11310b57cec5SDimitry Andric "May only branch on boolean predicates!");
11320b57cec5SDimitry Andric }
11330b57cec5SDimitry Andric
BranchInst(BasicBlock * IfTrue,InsertPosition InsertBefore)1134*0fca6ea1SDimitry Andric BranchInst::BranchInst(BasicBlock *IfTrue, InsertPosition InsertBefore)
11350b57cec5SDimitry Andric : Instruction(Type::getVoidTy(IfTrue->getContext()), Instruction::Br,
11360b57cec5SDimitry Andric OperandTraits<BranchInst>::op_end(this) - 1, 1,
11370b57cec5SDimitry Andric InsertBefore) {
11380b57cec5SDimitry Andric assert(IfTrue && "Branch destination may not be null!");
11390b57cec5SDimitry Andric Op<-1>() = IfTrue;
11400b57cec5SDimitry Andric }
11410b57cec5SDimitry Andric
BranchInst(BasicBlock * IfTrue,BasicBlock * IfFalse,Value * Cond,InsertPosition InsertBefore)11420b57cec5SDimitry Andric BranchInst::BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
1143*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
11440b57cec5SDimitry Andric : Instruction(Type::getVoidTy(IfTrue->getContext()), Instruction::Br,
11450b57cec5SDimitry Andric OperandTraits<BranchInst>::op_end(this) - 3, 3,
11460b57cec5SDimitry Andric InsertBefore) {
1147fe6060f1SDimitry Andric // Assign in order of operand index to make use-list order predictable.
11480b57cec5SDimitry Andric Op<-3>() = Cond;
1149fe6060f1SDimitry Andric Op<-2>() = IfFalse;
1150fe6060f1SDimitry Andric Op<-1>() = IfTrue;
11510b57cec5SDimitry Andric #ifndef NDEBUG
11520b57cec5SDimitry Andric AssertOK();
11530b57cec5SDimitry Andric #endif
11540b57cec5SDimitry Andric }
11550b57cec5SDimitry Andric
BranchInst(const BranchInst & BI)11560b57cec5SDimitry Andric BranchInst::BranchInst(const BranchInst &BI)
11570b57cec5SDimitry Andric : Instruction(Type::getVoidTy(BI.getContext()), Instruction::Br,
11580b57cec5SDimitry Andric OperandTraits<BranchInst>::op_end(this) - BI.getNumOperands(),
11590b57cec5SDimitry Andric BI.getNumOperands()) {
1160fe6060f1SDimitry Andric // Assign in order of operand index to make use-list order predictable.
11610b57cec5SDimitry Andric if (BI.getNumOperands() != 1) {
11620b57cec5SDimitry Andric assert(BI.getNumOperands() == 3 && "BR can have 1 or 3 operands!");
11630b57cec5SDimitry Andric Op<-3>() = BI.Op<-3>();
11640b57cec5SDimitry Andric Op<-2>() = BI.Op<-2>();
11650b57cec5SDimitry Andric }
1166fe6060f1SDimitry Andric Op<-1>() = BI.Op<-1>();
11670b57cec5SDimitry Andric SubclassOptionalData = BI.SubclassOptionalData;
11680b57cec5SDimitry Andric }
11690b57cec5SDimitry Andric
swapSuccessors()11700b57cec5SDimitry Andric void BranchInst::swapSuccessors() {
11710b57cec5SDimitry Andric assert(isConditional() &&
11720b57cec5SDimitry Andric "Cannot swap successors of an unconditional branch");
11730b57cec5SDimitry Andric Op<-1>().swap(Op<-2>());
11740b57cec5SDimitry Andric
11750b57cec5SDimitry Andric // Update profile metadata if present and it matches our structural
11760b57cec5SDimitry Andric // expectations.
11770b57cec5SDimitry Andric swapProfMetadata();
11780b57cec5SDimitry Andric }
11790b57cec5SDimitry Andric
11800b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11810b57cec5SDimitry Andric // AllocaInst Implementation
11820b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11830b57cec5SDimitry Andric
getAISize(LLVMContext & Context,Value * Amt)11840b57cec5SDimitry Andric static Value *getAISize(LLVMContext &Context, Value *Amt) {
11850b57cec5SDimitry Andric if (!Amt)
11860b57cec5SDimitry Andric Amt = ConstantInt::get(Type::getInt32Ty(Context), 1);
11870b57cec5SDimitry Andric else {
11880b57cec5SDimitry Andric assert(!isa<BasicBlock>(Amt) &&
11890b57cec5SDimitry Andric "Passed basic block into allocation size parameter! Use other ctor");
11900b57cec5SDimitry Andric assert(Amt->getType()->isIntegerTy() &&
11910b57cec5SDimitry Andric "Allocation array size is not an integer!");
11920b57cec5SDimitry Andric }
11930b57cec5SDimitry Andric return Amt;
11940b57cec5SDimitry Andric }
11950b57cec5SDimitry Andric
computeAllocaDefaultAlign(Type * Ty,InsertPosition Pos)1196*0fca6ea1SDimitry Andric static Align computeAllocaDefaultAlign(Type *Ty, InsertPosition Pos) {
1197*0fca6ea1SDimitry Andric assert(Pos.isValid() &&
1198*0fca6ea1SDimitry Andric "Insertion position cannot be null when alignment not provided!");
1199*0fca6ea1SDimitry Andric BasicBlock *BB = Pos.getBasicBlock();
12005ffd83dbSDimitry Andric assert(BB->getParent() &&
12015ffd83dbSDimitry Andric "BB must be in a Function when alignment not provided!");
1202*0fca6ea1SDimitry Andric const DataLayout &DL = BB->getDataLayout();
12035ffd83dbSDimitry Andric return DL.getPrefTypeAlign(Ty);
12045ffd83dbSDimitry Andric }
12055ffd83dbSDimitry Andric
AllocaInst(Type * Ty,unsigned AddrSpace,const Twine & Name,InsertPosition InsertBefore)12060b57cec5SDimitry Andric AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, const Twine &Name,
1207*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
12080b57cec5SDimitry Andric : AllocaInst(Ty, AddrSpace, /*ArraySize=*/nullptr, Name, InsertBefore) {}
12090b57cec5SDimitry Andric
AllocaInst(Type * Ty,unsigned AddrSpace,Value * ArraySize,const Twine & Name,InsertPosition InsertBefore)12100b57cec5SDimitry Andric AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize,
1211*0fca6ea1SDimitry Andric const Twine &Name, InsertPosition InsertBefore)
12125ffd83dbSDimitry Andric : AllocaInst(Ty, AddrSpace, ArraySize,
12135ffd83dbSDimitry Andric computeAllocaDefaultAlign(Ty, InsertBefore), Name,
12145ffd83dbSDimitry Andric InsertBefore) {}
12150b57cec5SDimitry Andric
AllocaInst(Type * Ty,unsigned AddrSpace,Value * ArraySize,Align Align,const Twine & Name,InsertPosition InsertBefore)12160b57cec5SDimitry Andric AllocaInst::AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize,
12175ffd83dbSDimitry Andric Align Align, const Twine &Name,
1218*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
12190b57cec5SDimitry Andric : UnaryInstruction(PointerType::get(Ty, AddrSpace), Alloca,
12200b57cec5SDimitry Andric getAISize(Ty->getContext(), ArraySize), InsertBefore),
12210b57cec5SDimitry Andric AllocatedType(Ty) {
12225ffd83dbSDimitry Andric setAlignment(Align);
12230b57cec5SDimitry Andric assert(!Ty->isVoidTy() && "Cannot allocate void!");
12240b57cec5SDimitry Andric setName(Name);
12250b57cec5SDimitry Andric }
12260b57cec5SDimitry Andric
isArrayAllocation() const12270b57cec5SDimitry Andric bool AllocaInst::isArrayAllocation() const {
12280b57cec5SDimitry Andric if (ConstantInt *CI = dyn_cast<ConstantInt>(getOperand(0)))
12290b57cec5SDimitry Andric return !CI->isOne();
12300b57cec5SDimitry Andric return true;
12310b57cec5SDimitry Andric }
12320b57cec5SDimitry Andric
12330b57cec5SDimitry Andric /// isStaticAlloca - Return true if this alloca is in the entry block of the
12340b57cec5SDimitry Andric /// function and is a constant size. If so, the code generator will fold it
12350b57cec5SDimitry Andric /// into the prolog/epilog code, so it is basically free.
isStaticAlloca() const12360b57cec5SDimitry Andric bool AllocaInst::isStaticAlloca() const {
12370b57cec5SDimitry Andric // Must be constant size.
12380b57cec5SDimitry Andric if (!isa<ConstantInt>(getArraySize())) return false;
12390b57cec5SDimitry Andric
12400b57cec5SDimitry Andric // Must be in the entry block.
12410b57cec5SDimitry Andric const BasicBlock *Parent = getParent();
1242bdd1243dSDimitry Andric return Parent->isEntryBlock() && !isUsedWithInAlloca();
12430b57cec5SDimitry Andric }
12440b57cec5SDimitry Andric
12450b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12460b57cec5SDimitry Andric // LoadInst Implementation
12470b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12480b57cec5SDimitry Andric
AssertOK()12490b57cec5SDimitry Andric void LoadInst::AssertOK() {
12500b57cec5SDimitry Andric assert(getOperand(0)->getType()->isPointerTy() &&
12510b57cec5SDimitry Andric "Ptr must have pointer type.");
12520b57cec5SDimitry Andric }
12530b57cec5SDimitry Andric
computeLoadStoreDefaultAlign(Type * Ty,InsertPosition Pos)1254*0fca6ea1SDimitry Andric static Align computeLoadStoreDefaultAlign(Type *Ty, InsertPosition Pos) {
1255*0fca6ea1SDimitry Andric assert(Pos.isValid() &&
1256*0fca6ea1SDimitry Andric "Insertion position cannot be null when alignment not provided!");
1257*0fca6ea1SDimitry Andric BasicBlock *BB = Pos.getBasicBlock();
12585ffd83dbSDimitry Andric assert(BB->getParent() &&
12595ffd83dbSDimitry Andric "BB must be in a Function when alignment not provided!");
1260*0fca6ea1SDimitry Andric const DataLayout &DL = BB->getDataLayout();
12615ffd83dbSDimitry Andric return DL.getABITypeAlign(Ty);
12625ffd83dbSDimitry Andric }
12635ffd83dbSDimitry Andric
LoadInst(Type * Ty,Value * Ptr,const Twine & Name,InsertPosition InsertBef)12640b57cec5SDimitry Andric LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name,
1265*0fca6ea1SDimitry Andric InsertPosition InsertBef)
12660b57cec5SDimitry Andric : LoadInst(Ty, Ptr, Name, /*isVolatile=*/false, InsertBef) {}
12670b57cec5SDimitry Andric
LoadInst(Type * Ty,Value * Ptr,const Twine & Name,bool isVolatile,InsertPosition InsertBef)12680b57cec5SDimitry Andric LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile,
1269*0fca6ea1SDimitry Andric InsertPosition InsertBef)
12705ffd83dbSDimitry Andric : LoadInst(Ty, Ptr, Name, isVolatile,
12715ffd83dbSDimitry Andric computeLoadStoreDefaultAlign(Ty, InsertBef), InsertBef) {}
12720b57cec5SDimitry Andric
LoadInst(Type * Ty,Value * Ptr,const Twine & Name,bool isVolatile,Align Align,InsertPosition InsertBef)12730b57cec5SDimitry Andric LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile,
1274*0fca6ea1SDimitry Andric Align Align, InsertPosition InsertBef)
12750b57cec5SDimitry Andric : LoadInst(Ty, Ptr, Name, isVolatile, Align, AtomicOrdering::NotAtomic,
12760b57cec5SDimitry Andric SyncScope::System, InsertBef) {}
12770b57cec5SDimitry Andric
LoadInst(Type * Ty,Value * Ptr,const Twine & Name,bool isVolatile,Align Align,AtomicOrdering Order,SyncScope::ID SSID,InsertPosition InsertBef)12780b57cec5SDimitry Andric LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile,
12795ffd83dbSDimitry Andric Align Align, AtomicOrdering Order, SyncScope::ID SSID,
1280*0fca6ea1SDimitry Andric InsertPosition InsertBef)
12810b57cec5SDimitry Andric : UnaryInstruction(Ty, Load, Ptr, InsertBef) {
12820b57cec5SDimitry Andric setVolatile(isVolatile);
12830b57cec5SDimitry Andric setAlignment(Align);
12840b57cec5SDimitry Andric setAtomic(Order, SSID);
12850b57cec5SDimitry Andric AssertOK();
12860b57cec5SDimitry Andric setName(Name);
12870b57cec5SDimitry Andric }
12880b57cec5SDimitry Andric
12890b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12900b57cec5SDimitry Andric // StoreInst Implementation
12910b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12920b57cec5SDimitry Andric
AssertOK()12930b57cec5SDimitry Andric void StoreInst::AssertOK() {
12940b57cec5SDimitry Andric assert(getOperand(0) && getOperand(1) && "Both operands must be non-null!");
12950b57cec5SDimitry Andric assert(getOperand(1)->getType()->isPointerTy() &&
12960b57cec5SDimitry Andric "Ptr must have pointer type!");
12970b57cec5SDimitry Andric }
12980b57cec5SDimitry Andric
StoreInst(Value * val,Value * addr,InsertPosition InsertBefore)1299*0fca6ea1SDimitry Andric StoreInst::StoreInst(Value *val, Value *addr, InsertPosition InsertBefore)
13005f757f3fSDimitry Andric : StoreInst(val, addr, /*isVolatile=*/false, InsertBefore) {}
13015f757f3fSDimitry Andric
StoreInst(Value * val,Value * addr,bool isVolatile,InsertPosition InsertBefore)13020b57cec5SDimitry Andric StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
1303*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
13045ffd83dbSDimitry Andric : StoreInst(val, addr, isVolatile,
13055ffd83dbSDimitry Andric computeLoadStoreDefaultAlign(val->getType(), InsertBefore),
13065ffd83dbSDimitry Andric InsertBefore) {}
13070b57cec5SDimitry Andric
StoreInst(Value * val,Value * addr,bool isVolatile,Align Align,InsertPosition InsertBefore)13085ffd83dbSDimitry Andric StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, Align Align,
1309*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
13105f757f3fSDimitry Andric : StoreInst(val, addr, isVolatile, Align, AtomicOrdering::NotAtomic,
13115f757f3fSDimitry Andric SyncScope::System, InsertBefore) {}
13125f757f3fSDimitry Andric
StoreInst(Value * val,Value * addr,bool isVolatile,Align Align,AtomicOrdering Order,SyncScope::ID SSID,InsertPosition InsertBefore)13135f757f3fSDimitry Andric StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, Align Align,
13148bcb0991SDimitry Andric AtomicOrdering Order, SyncScope::ID SSID,
1315*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
13160b57cec5SDimitry Andric : Instruction(Type::getVoidTy(val->getContext()), Store,
13170b57cec5SDimitry Andric OperandTraits<StoreInst>::op_begin(this),
13188bcb0991SDimitry Andric OperandTraits<StoreInst>::operands(this), InsertBefore) {
13190b57cec5SDimitry Andric Op<0>() = val;
13200b57cec5SDimitry Andric Op<1>() = addr;
13210b57cec5SDimitry Andric setVolatile(isVolatile);
13220b57cec5SDimitry Andric setAlignment(Align);
13230b57cec5SDimitry Andric setAtomic(Order, SSID);
13240b57cec5SDimitry Andric AssertOK();
13250b57cec5SDimitry Andric }
13260b57cec5SDimitry Andric
13270b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13280b57cec5SDimitry Andric // AtomicCmpXchgInst Implementation
13290b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13300b57cec5SDimitry Andric
Init(Value * Ptr,Value * Cmp,Value * NewVal,Align Alignment,AtomicOrdering SuccessOrdering,AtomicOrdering FailureOrdering,SyncScope::ID SSID)13310b57cec5SDimitry Andric void AtomicCmpXchgInst::Init(Value *Ptr, Value *Cmp, Value *NewVal,
13325ffd83dbSDimitry Andric Align Alignment, AtomicOrdering SuccessOrdering,
13330b57cec5SDimitry Andric AtomicOrdering FailureOrdering,
13340b57cec5SDimitry Andric SyncScope::ID SSID) {
13350b57cec5SDimitry Andric Op<0>() = Ptr;
13360b57cec5SDimitry Andric Op<1>() = Cmp;
13370b57cec5SDimitry Andric Op<2>() = NewVal;
13380b57cec5SDimitry Andric setSuccessOrdering(SuccessOrdering);
13390b57cec5SDimitry Andric setFailureOrdering(FailureOrdering);
13400b57cec5SDimitry Andric setSyncScopeID(SSID);
13415ffd83dbSDimitry Andric setAlignment(Alignment);
13420b57cec5SDimitry Andric
13430b57cec5SDimitry Andric assert(getOperand(0) && getOperand(1) && getOperand(2) &&
13440b57cec5SDimitry Andric "All operands must be non-null!");
13450b57cec5SDimitry Andric assert(getOperand(0)->getType()->isPointerTy() &&
13460b57cec5SDimitry Andric "Ptr must have pointer type!");
1347fe6060f1SDimitry Andric assert(getOperand(1)->getType() == getOperand(2)->getType() &&
1348fe6060f1SDimitry Andric "Cmp type and NewVal type must be same!");
13490b57cec5SDimitry Andric }
13500b57cec5SDimitry Andric
AtomicCmpXchgInst(Value * Ptr,Value * Cmp,Value * NewVal,Align Alignment,AtomicOrdering SuccessOrdering,AtomicOrdering FailureOrdering,SyncScope::ID SSID,InsertPosition InsertBefore)13510b57cec5SDimitry Andric AtomicCmpXchgInst::AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal,
13525ffd83dbSDimitry Andric Align Alignment,
13530b57cec5SDimitry Andric AtomicOrdering SuccessOrdering,
13540b57cec5SDimitry Andric AtomicOrdering FailureOrdering,
13550b57cec5SDimitry Andric SyncScope::ID SSID,
1356*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
13570b57cec5SDimitry Andric : Instruction(
13580b57cec5SDimitry Andric StructType::get(Cmp->getType(), Type::getInt1Ty(Cmp->getContext())),
13590b57cec5SDimitry Andric AtomicCmpXchg, OperandTraits<AtomicCmpXchgInst>::op_begin(this),
13600b57cec5SDimitry Andric OperandTraits<AtomicCmpXchgInst>::operands(this), InsertBefore) {
13615ffd83dbSDimitry Andric Init(Ptr, Cmp, NewVal, Alignment, SuccessOrdering, FailureOrdering, SSID);
13620b57cec5SDimitry Andric }
13630b57cec5SDimitry Andric
13640b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13650b57cec5SDimitry Andric // AtomicRMWInst Implementation
13660b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13670b57cec5SDimitry Andric
Init(BinOp Operation,Value * Ptr,Value * Val,Align Alignment,AtomicOrdering Ordering,SyncScope::ID SSID)13680b57cec5SDimitry Andric void AtomicRMWInst::Init(BinOp Operation, Value *Ptr, Value *Val,
13695ffd83dbSDimitry Andric Align Alignment, AtomicOrdering Ordering,
13700b57cec5SDimitry Andric SyncScope::ID SSID) {
1371972a253aSDimitry Andric assert(Ordering != AtomicOrdering::NotAtomic &&
1372972a253aSDimitry Andric "atomicrmw instructions can only be atomic.");
1373972a253aSDimitry Andric assert(Ordering != AtomicOrdering::Unordered &&
1374972a253aSDimitry Andric "atomicrmw instructions cannot be unordered.");
13750b57cec5SDimitry Andric Op<0>() = Ptr;
13760b57cec5SDimitry Andric Op<1>() = Val;
13770b57cec5SDimitry Andric setOperation(Operation);
13780b57cec5SDimitry Andric setOrdering(Ordering);
13790b57cec5SDimitry Andric setSyncScopeID(SSID);
13805ffd83dbSDimitry Andric setAlignment(Alignment);
13810b57cec5SDimitry Andric
1382*0fca6ea1SDimitry Andric assert(getOperand(0) && getOperand(1) && "All operands must be non-null!");
13830b57cec5SDimitry Andric assert(getOperand(0)->getType()->isPointerTy() &&
13840b57cec5SDimitry Andric "Ptr must have pointer type!");
13850b57cec5SDimitry Andric assert(Ordering != AtomicOrdering::NotAtomic &&
13860b57cec5SDimitry Andric "AtomicRMW instructions must be atomic!");
13870b57cec5SDimitry Andric }
13880b57cec5SDimitry Andric
AtomicRMWInst(BinOp Operation,Value * Ptr,Value * Val,Align Alignment,AtomicOrdering Ordering,SyncScope::ID SSID,InsertPosition InsertBefore)13890b57cec5SDimitry Andric AtomicRMWInst::AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val,
13905ffd83dbSDimitry Andric Align Alignment, AtomicOrdering Ordering,
1391*0fca6ea1SDimitry Andric SyncScope::ID SSID, InsertPosition InsertBefore)
13920b57cec5SDimitry Andric : Instruction(Val->getType(), AtomicRMW,
13930b57cec5SDimitry Andric OperandTraits<AtomicRMWInst>::op_begin(this),
13945ffd83dbSDimitry Andric OperandTraits<AtomicRMWInst>::operands(this), InsertBefore) {
13955ffd83dbSDimitry Andric Init(Operation, Ptr, Val, Alignment, Ordering, SSID);
13960b57cec5SDimitry Andric }
13970b57cec5SDimitry Andric
getOperationName(BinOp Op)13980b57cec5SDimitry Andric StringRef AtomicRMWInst::getOperationName(BinOp Op) {
13990b57cec5SDimitry Andric switch (Op) {
14000b57cec5SDimitry Andric case AtomicRMWInst::Xchg:
14010b57cec5SDimitry Andric return "xchg";
14020b57cec5SDimitry Andric case AtomicRMWInst::Add:
14030b57cec5SDimitry Andric return "add";
14040b57cec5SDimitry Andric case AtomicRMWInst::Sub:
14050b57cec5SDimitry Andric return "sub";
14060b57cec5SDimitry Andric case AtomicRMWInst::And:
14070b57cec5SDimitry Andric return "and";
14080b57cec5SDimitry Andric case AtomicRMWInst::Nand:
14090b57cec5SDimitry Andric return "nand";
14100b57cec5SDimitry Andric case AtomicRMWInst::Or:
14110b57cec5SDimitry Andric return "or";
14120b57cec5SDimitry Andric case AtomicRMWInst::Xor:
14130b57cec5SDimitry Andric return "xor";
14140b57cec5SDimitry Andric case AtomicRMWInst::Max:
14150b57cec5SDimitry Andric return "max";
14160b57cec5SDimitry Andric case AtomicRMWInst::Min:
14170b57cec5SDimitry Andric return "min";
14180b57cec5SDimitry Andric case AtomicRMWInst::UMax:
14190b57cec5SDimitry Andric return "umax";
14200b57cec5SDimitry Andric case AtomicRMWInst::UMin:
14210b57cec5SDimitry Andric return "umin";
14220b57cec5SDimitry Andric case AtomicRMWInst::FAdd:
14230b57cec5SDimitry Andric return "fadd";
14240b57cec5SDimitry Andric case AtomicRMWInst::FSub:
14250b57cec5SDimitry Andric return "fsub";
1426753f127fSDimitry Andric case AtomicRMWInst::FMax:
1427753f127fSDimitry Andric return "fmax";
1428753f127fSDimitry Andric case AtomicRMWInst::FMin:
1429753f127fSDimitry Andric return "fmin";
1430bdd1243dSDimitry Andric case AtomicRMWInst::UIncWrap:
1431bdd1243dSDimitry Andric return "uinc_wrap";
1432bdd1243dSDimitry Andric case AtomicRMWInst::UDecWrap:
1433bdd1243dSDimitry Andric return "udec_wrap";
14340b57cec5SDimitry Andric case AtomicRMWInst::BAD_BINOP:
14350b57cec5SDimitry Andric return "<invalid operation>";
14360b57cec5SDimitry Andric }
14370b57cec5SDimitry Andric
14380b57cec5SDimitry Andric llvm_unreachable("invalid atomicrmw operation");
14390b57cec5SDimitry Andric }
14400b57cec5SDimitry Andric
14410b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14420b57cec5SDimitry Andric // FenceInst Implementation
14430b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14440b57cec5SDimitry Andric
FenceInst(LLVMContext & C,AtomicOrdering Ordering,SyncScope::ID SSID,InsertPosition InsertBefore)14450b57cec5SDimitry Andric FenceInst::FenceInst(LLVMContext &C, AtomicOrdering Ordering,
1446*0fca6ea1SDimitry Andric SyncScope::ID SSID, InsertPosition InsertBefore)
14470b57cec5SDimitry Andric : Instruction(Type::getVoidTy(C), Fence, nullptr, 0, InsertBefore) {
14480b57cec5SDimitry Andric setOrdering(Ordering);
14490b57cec5SDimitry Andric setSyncScopeID(SSID);
14500b57cec5SDimitry Andric }
14510b57cec5SDimitry Andric
14520b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14530b57cec5SDimitry Andric // GetElementPtrInst Implementation
14540b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14550b57cec5SDimitry Andric
init(Value * Ptr,ArrayRef<Value * > IdxList,const Twine & Name)14560b57cec5SDimitry Andric void GetElementPtrInst::init(Value *Ptr, ArrayRef<Value *> IdxList,
14570b57cec5SDimitry Andric const Twine &Name) {
14580b57cec5SDimitry Andric assert(getNumOperands() == 1 + IdxList.size() &&
14590b57cec5SDimitry Andric "NumOperands not initialized?");
14600b57cec5SDimitry Andric Op<0>() = Ptr;
14610b57cec5SDimitry Andric llvm::copy(IdxList, op_begin() + 1);
14620b57cec5SDimitry Andric setName(Name);
14630b57cec5SDimitry Andric }
14640b57cec5SDimitry Andric
GetElementPtrInst(const GetElementPtrInst & GEPI)14650b57cec5SDimitry Andric GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI)
14660b57cec5SDimitry Andric : Instruction(GEPI.getType(), GetElementPtr,
14670b57cec5SDimitry Andric OperandTraits<GetElementPtrInst>::op_end(this) -
14680b57cec5SDimitry Andric GEPI.getNumOperands(),
14690b57cec5SDimitry Andric GEPI.getNumOperands()),
14700b57cec5SDimitry Andric SourceElementType(GEPI.SourceElementType),
14710b57cec5SDimitry Andric ResultElementType(GEPI.ResultElementType) {
14720b57cec5SDimitry Andric std::copy(GEPI.op_begin(), GEPI.op_end(), op_begin());
14730b57cec5SDimitry Andric SubclassOptionalData = GEPI.SubclassOptionalData;
14740b57cec5SDimitry Andric }
14750b57cec5SDimitry Andric
getTypeAtIndex(Type * Ty,Value * Idx)14765ffd83dbSDimitry Andric Type *GetElementPtrInst::getTypeAtIndex(Type *Ty, Value *Idx) {
14775ffd83dbSDimitry Andric if (auto *Struct = dyn_cast<StructType>(Ty)) {
14785ffd83dbSDimitry Andric if (!Struct->indexValid(Idx))
14790b57cec5SDimitry Andric return nullptr;
14805ffd83dbSDimitry Andric return Struct->getTypeAtIndex(Idx);
14810b57cec5SDimitry Andric }
14825ffd83dbSDimitry Andric if (!Idx->getType()->isIntOrIntVectorTy())
14835ffd83dbSDimitry Andric return nullptr;
14845ffd83dbSDimitry Andric if (auto *Array = dyn_cast<ArrayType>(Ty))
14855ffd83dbSDimitry Andric return Array->getElementType();
14865ffd83dbSDimitry Andric if (auto *Vector = dyn_cast<VectorType>(Ty))
14875ffd83dbSDimitry Andric return Vector->getElementType();
14885ffd83dbSDimitry Andric return nullptr;
14895ffd83dbSDimitry Andric }
14905ffd83dbSDimitry Andric
getTypeAtIndex(Type * Ty,uint64_t Idx)14915ffd83dbSDimitry Andric Type *GetElementPtrInst::getTypeAtIndex(Type *Ty, uint64_t Idx) {
14925ffd83dbSDimitry Andric if (auto *Struct = dyn_cast<StructType>(Ty)) {
14935ffd83dbSDimitry Andric if (Idx >= Struct->getNumElements())
14945ffd83dbSDimitry Andric return nullptr;
14955ffd83dbSDimitry Andric return Struct->getElementType(Idx);
14965ffd83dbSDimitry Andric }
14975ffd83dbSDimitry Andric if (auto *Array = dyn_cast<ArrayType>(Ty))
14985ffd83dbSDimitry Andric return Array->getElementType();
14995ffd83dbSDimitry Andric if (auto *Vector = dyn_cast<VectorType>(Ty))
15005ffd83dbSDimitry Andric return Vector->getElementType();
15015ffd83dbSDimitry Andric return nullptr;
15025ffd83dbSDimitry Andric }
15035ffd83dbSDimitry Andric
15045ffd83dbSDimitry Andric template <typename IndexTy>
getIndexedTypeInternal(Type * Ty,ArrayRef<IndexTy> IdxList)15055ffd83dbSDimitry Andric static Type *getIndexedTypeInternal(Type *Ty, ArrayRef<IndexTy> IdxList) {
15065ffd83dbSDimitry Andric if (IdxList.empty())
15075ffd83dbSDimitry Andric return Ty;
15085ffd83dbSDimitry Andric for (IndexTy V : IdxList.slice(1)) {
15095ffd83dbSDimitry Andric Ty = GetElementPtrInst::getTypeAtIndex(Ty, V);
15105ffd83dbSDimitry Andric if (!Ty)
15115ffd83dbSDimitry Andric return Ty;
15125ffd83dbSDimitry Andric }
15135ffd83dbSDimitry Andric return Ty;
15140b57cec5SDimitry Andric }
15150b57cec5SDimitry Andric
getIndexedType(Type * Ty,ArrayRef<Value * > IdxList)15160b57cec5SDimitry Andric Type *GetElementPtrInst::getIndexedType(Type *Ty, ArrayRef<Value *> IdxList) {
15170b57cec5SDimitry Andric return getIndexedTypeInternal(Ty, IdxList);
15180b57cec5SDimitry Andric }
15190b57cec5SDimitry Andric
getIndexedType(Type * Ty,ArrayRef<Constant * > IdxList)15200b57cec5SDimitry Andric Type *GetElementPtrInst::getIndexedType(Type *Ty,
15210b57cec5SDimitry Andric ArrayRef<Constant *> IdxList) {
15220b57cec5SDimitry Andric return getIndexedTypeInternal(Ty, IdxList);
15230b57cec5SDimitry Andric }
15240b57cec5SDimitry Andric
getIndexedType(Type * Ty,ArrayRef<uint64_t> IdxList)15250b57cec5SDimitry Andric Type *GetElementPtrInst::getIndexedType(Type *Ty, ArrayRef<uint64_t> IdxList) {
15260b57cec5SDimitry Andric return getIndexedTypeInternal(Ty, IdxList);
15270b57cec5SDimitry Andric }
15280b57cec5SDimitry Andric
15290b57cec5SDimitry Andric /// hasAllZeroIndices - Return true if all of the indices of this GEP are
15300b57cec5SDimitry Andric /// zeros. If so, the result pointer and the first operand have the same
15310b57cec5SDimitry Andric /// value, just potentially different types.
hasAllZeroIndices() const15320b57cec5SDimitry Andric bool GetElementPtrInst::hasAllZeroIndices() const {
15330b57cec5SDimitry Andric for (unsigned i = 1, e = getNumOperands(); i != e; ++i) {
15340b57cec5SDimitry Andric if (ConstantInt *CI = dyn_cast<ConstantInt>(getOperand(i))) {
15350b57cec5SDimitry Andric if (!CI->isZero()) return false;
15360b57cec5SDimitry Andric } else {
15370b57cec5SDimitry Andric return false;
15380b57cec5SDimitry Andric }
15390b57cec5SDimitry Andric }
15400b57cec5SDimitry Andric return true;
15410b57cec5SDimitry Andric }
15420b57cec5SDimitry Andric
15430b57cec5SDimitry Andric /// hasAllConstantIndices - Return true if all of the indices of this GEP are
15440b57cec5SDimitry Andric /// constant integers. If so, the result pointer and the first operand have
15450b57cec5SDimitry Andric /// a constant offset between them.
hasAllConstantIndices() const15460b57cec5SDimitry Andric bool GetElementPtrInst::hasAllConstantIndices() const {
15470b57cec5SDimitry Andric for (unsigned i = 1, e = getNumOperands(); i != e; ++i) {
15480b57cec5SDimitry Andric if (!isa<ConstantInt>(getOperand(i)))
15490b57cec5SDimitry Andric return false;
15500b57cec5SDimitry Andric }
15510b57cec5SDimitry Andric return true;
15520b57cec5SDimitry Andric }
15530b57cec5SDimitry Andric
setNoWrapFlags(GEPNoWrapFlags NW)1554*0fca6ea1SDimitry Andric void GetElementPtrInst::setNoWrapFlags(GEPNoWrapFlags NW) {
1555*0fca6ea1SDimitry Andric SubclassOptionalData = NW.getRaw();
1556*0fca6ea1SDimitry Andric }
1557*0fca6ea1SDimitry Andric
setIsInBounds(bool B)15580b57cec5SDimitry Andric void GetElementPtrInst::setIsInBounds(bool B) {
1559*0fca6ea1SDimitry Andric GEPNoWrapFlags NW = cast<GEPOperator>(this)->getNoWrapFlags();
1560*0fca6ea1SDimitry Andric if (B)
1561*0fca6ea1SDimitry Andric NW |= GEPNoWrapFlags::inBounds();
1562*0fca6ea1SDimitry Andric else
1563*0fca6ea1SDimitry Andric NW = NW.withoutInBounds();
1564*0fca6ea1SDimitry Andric setNoWrapFlags(NW);
1565*0fca6ea1SDimitry Andric }
1566*0fca6ea1SDimitry Andric
getNoWrapFlags() const1567*0fca6ea1SDimitry Andric GEPNoWrapFlags GetElementPtrInst::getNoWrapFlags() const {
1568*0fca6ea1SDimitry Andric return cast<GEPOperator>(this)->getNoWrapFlags();
15690b57cec5SDimitry Andric }
15700b57cec5SDimitry Andric
isInBounds() const15710b57cec5SDimitry Andric bool GetElementPtrInst::isInBounds() const {
15720b57cec5SDimitry Andric return cast<GEPOperator>(this)->isInBounds();
15730b57cec5SDimitry Andric }
15740b57cec5SDimitry Andric
hasNoUnsignedSignedWrap() const1575*0fca6ea1SDimitry Andric bool GetElementPtrInst::hasNoUnsignedSignedWrap() const {
1576*0fca6ea1SDimitry Andric return cast<GEPOperator>(this)->hasNoUnsignedSignedWrap();
1577*0fca6ea1SDimitry Andric }
1578*0fca6ea1SDimitry Andric
hasNoUnsignedWrap() const1579*0fca6ea1SDimitry Andric bool GetElementPtrInst::hasNoUnsignedWrap() const {
1580*0fca6ea1SDimitry Andric return cast<GEPOperator>(this)->hasNoUnsignedWrap();
1581*0fca6ea1SDimitry Andric }
1582*0fca6ea1SDimitry Andric
accumulateConstantOffset(const DataLayout & DL,APInt & Offset) const15830b57cec5SDimitry Andric bool GetElementPtrInst::accumulateConstantOffset(const DataLayout &DL,
15840b57cec5SDimitry Andric APInt &Offset) const {
15850b57cec5SDimitry Andric // Delegate to the generic GEPOperator implementation.
15860b57cec5SDimitry Andric return cast<GEPOperator>(this)->accumulateConstantOffset(DL, Offset);
15870b57cec5SDimitry Andric }
15880b57cec5SDimitry Andric
collectOffset(const DataLayout & DL,unsigned BitWidth,MapVector<Value *,APInt> & VariableOffsets,APInt & ConstantOffset) const1589fe6060f1SDimitry Andric bool GetElementPtrInst::collectOffset(
1590fe6060f1SDimitry Andric const DataLayout &DL, unsigned BitWidth,
1591fe6060f1SDimitry Andric MapVector<Value *, APInt> &VariableOffsets,
1592fe6060f1SDimitry Andric APInt &ConstantOffset) const {
1593fe6060f1SDimitry Andric // Delegate to the generic GEPOperator implementation.
1594fe6060f1SDimitry Andric return cast<GEPOperator>(this)->collectOffset(DL, BitWidth, VariableOffsets,
1595fe6060f1SDimitry Andric ConstantOffset);
1596fe6060f1SDimitry Andric }
1597fe6060f1SDimitry Andric
15980b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
15990b57cec5SDimitry Andric // ExtractElementInst Implementation
16000b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
16010b57cec5SDimitry Andric
ExtractElementInst(Value * Val,Value * Index,const Twine & Name,InsertPosition InsertBef)16020b57cec5SDimitry Andric ExtractElementInst::ExtractElementInst(Value *Val, Value *Index,
16030b57cec5SDimitry Andric const Twine &Name,
1604*0fca6ea1SDimitry Andric InsertPosition InsertBef)
1605*0fca6ea1SDimitry Andric : Instruction(
1606*0fca6ea1SDimitry Andric cast<VectorType>(Val->getType())->getElementType(), ExtractElement,
1607*0fca6ea1SDimitry Andric OperandTraits<ExtractElementInst>::op_begin(this), 2, InsertBef) {
16080b57cec5SDimitry Andric assert(isValidOperands(Val, Index) &&
16090b57cec5SDimitry Andric "Invalid extractelement instruction operands!");
16100b57cec5SDimitry Andric Op<0>() = Val;
16110b57cec5SDimitry Andric Op<1>() = Index;
16120b57cec5SDimitry Andric setName(Name);
16130b57cec5SDimitry Andric }
16140b57cec5SDimitry Andric
isValidOperands(const Value * Val,const Value * Index)16150b57cec5SDimitry Andric bool ExtractElementInst::isValidOperands(const Value *Val, const Value *Index) {
16160b57cec5SDimitry Andric if (!Val->getType()->isVectorTy() || !Index->getType()->isIntegerTy())
16170b57cec5SDimitry Andric return false;
16180b57cec5SDimitry Andric return true;
16190b57cec5SDimitry Andric }
16200b57cec5SDimitry Andric
16210b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
16220b57cec5SDimitry Andric // InsertElementInst Implementation
16230b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
16240b57cec5SDimitry Andric
InsertElementInst(Value * Vec,Value * Elt,Value * Index,const Twine & Name,InsertPosition InsertBef)16250b57cec5SDimitry Andric InsertElementInst::InsertElementInst(Value *Vec, Value *Elt, Value *Index,
16260b57cec5SDimitry Andric const Twine &Name,
1627*0fca6ea1SDimitry Andric InsertPosition InsertBef)
16280b57cec5SDimitry Andric : Instruction(Vec->getType(), InsertElement,
1629*0fca6ea1SDimitry Andric OperandTraits<InsertElementInst>::op_begin(this), 3,
1630*0fca6ea1SDimitry Andric InsertBef) {
16310b57cec5SDimitry Andric assert(isValidOperands(Vec, Elt, Index) &&
16320b57cec5SDimitry Andric "Invalid insertelement instruction operands!");
16330b57cec5SDimitry Andric Op<0>() = Vec;
16340b57cec5SDimitry Andric Op<1>() = Elt;
16350b57cec5SDimitry Andric Op<2>() = Index;
16360b57cec5SDimitry Andric setName(Name);
16370b57cec5SDimitry Andric }
16380b57cec5SDimitry Andric
isValidOperands(const Value * Vec,const Value * Elt,const Value * Index)16390b57cec5SDimitry Andric bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt,
16400b57cec5SDimitry Andric const Value *Index) {
16410b57cec5SDimitry Andric if (!Vec->getType()->isVectorTy())
16420b57cec5SDimitry Andric return false; // First operand of insertelement must be vector type.
16430b57cec5SDimitry Andric
16440b57cec5SDimitry Andric if (Elt->getType() != cast<VectorType>(Vec->getType())->getElementType())
16450b57cec5SDimitry Andric return false;// Second operand of insertelement must be vector element type.
16460b57cec5SDimitry Andric
16470b57cec5SDimitry Andric if (!Index->getType()->isIntegerTy())
16480b57cec5SDimitry Andric return false; // Third operand of insertelement must be i32.
16490b57cec5SDimitry Andric return true;
16500b57cec5SDimitry Andric }
16510b57cec5SDimitry Andric
16520b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
16530b57cec5SDimitry Andric // ShuffleVectorInst Implementation
16540b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
16550b57cec5SDimitry Andric
createPlaceholderForShuffleVector(Value * V)1656349cc55cSDimitry Andric static Value *createPlaceholderForShuffleVector(Value *V) {
1657349cc55cSDimitry Andric assert(V && "Cannot create placeholder of nullptr V");
1658349cc55cSDimitry Andric return PoisonValue::get(V->getType());
1659349cc55cSDimitry Andric }
1660349cc55cSDimitry Andric
ShuffleVectorInst(Value * V1,Value * Mask,const Twine & Name,InsertPosition InsertBefore)1661349cc55cSDimitry Andric ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *Mask, const Twine &Name,
1662*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
1663349cc55cSDimitry Andric : ShuffleVectorInst(V1, createPlaceholderForShuffleVector(V1), Mask, Name,
1664349cc55cSDimitry Andric InsertBefore) {}
1665349cc55cSDimitry Andric
ShuffleVectorInst(Value * V1,ArrayRef<int> Mask,const Twine & Name,InsertPosition InsertBefore)1666349cc55cSDimitry Andric ShuffleVectorInst::ShuffleVectorInst(Value *V1, ArrayRef<int> Mask,
1667349cc55cSDimitry Andric const Twine &Name,
1668*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
1669349cc55cSDimitry Andric : ShuffleVectorInst(V1, createPlaceholderForShuffleVector(V1), Mask, Name,
1670349cc55cSDimitry Andric InsertBefore) {}
1671349cc55cSDimitry Andric
ShuffleVectorInst(Value * V1,Value * V2,Value * Mask,const Twine & Name,InsertPosition InsertBefore)16720b57cec5SDimitry Andric ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
16730b57cec5SDimitry Andric const Twine &Name,
1674*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
16755ffd83dbSDimitry Andric : Instruction(
16765ffd83dbSDimitry Andric VectorType::get(cast<VectorType>(V1->getType())->getElementType(),
16778bcb0991SDimitry Andric cast<VectorType>(Mask->getType())->getElementCount()),
16785ffd83dbSDimitry Andric ShuffleVector, OperandTraits<ShuffleVectorInst>::op_begin(this),
16795ffd83dbSDimitry Andric OperandTraits<ShuffleVectorInst>::operands(this), InsertBefore) {
16800b57cec5SDimitry Andric assert(isValidOperands(V1, V2, Mask) &&
16810b57cec5SDimitry Andric "Invalid shuffle vector instruction operands!");
16825ffd83dbSDimitry Andric
16830b57cec5SDimitry Andric Op<0>() = V1;
16840b57cec5SDimitry Andric Op<1>() = V2;
16855ffd83dbSDimitry Andric SmallVector<int, 16> MaskArr;
16865ffd83dbSDimitry Andric getShuffleMask(cast<Constant>(Mask), MaskArr);
16875ffd83dbSDimitry Andric setShuffleMask(MaskArr);
16880b57cec5SDimitry Andric setName(Name);
16890b57cec5SDimitry Andric }
16900b57cec5SDimitry Andric
ShuffleVectorInst(Value * V1,Value * V2,ArrayRef<int> Mask,const Twine & Name,InsertPosition InsertBefore)16915ffd83dbSDimitry Andric ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, ArrayRef<int> Mask,
16925ffd83dbSDimitry Andric const Twine &Name,
1693*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
16945ffd83dbSDimitry Andric : Instruction(
16955ffd83dbSDimitry Andric VectorType::get(cast<VectorType>(V1->getType())->getElementType(),
16965ffd83dbSDimitry Andric Mask.size(), isa<ScalableVectorType>(V1->getType())),
16975ffd83dbSDimitry Andric ShuffleVector, OperandTraits<ShuffleVectorInst>::op_begin(this),
16985ffd83dbSDimitry Andric OperandTraits<ShuffleVectorInst>::operands(this), InsertBefore) {
16995ffd83dbSDimitry Andric assert(isValidOperands(V1, V2, Mask) &&
17005ffd83dbSDimitry Andric "Invalid shuffle vector instruction operands!");
17015ffd83dbSDimitry Andric Op<0>() = V1;
17025ffd83dbSDimitry Andric Op<1>() = V2;
17035ffd83dbSDimitry Andric setShuffleMask(Mask);
17045ffd83dbSDimitry Andric setName(Name);
17055ffd83dbSDimitry Andric }
17065ffd83dbSDimitry Andric
commute()17070b57cec5SDimitry Andric void ShuffleVectorInst::commute() {
1708e8d8bef9SDimitry Andric int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
17095ffd83dbSDimitry Andric int NumMaskElts = ShuffleMask.size();
17105ffd83dbSDimitry Andric SmallVector<int, 16> NewMask(NumMaskElts);
17110b57cec5SDimitry Andric for (int i = 0; i != NumMaskElts; ++i) {
17120b57cec5SDimitry Andric int MaskElt = getMaskValue(i);
171306c3fb27SDimitry Andric if (MaskElt == PoisonMaskElem) {
171406c3fb27SDimitry Andric NewMask[i] = PoisonMaskElem;
17150b57cec5SDimitry Andric continue;
17160b57cec5SDimitry Andric }
17170b57cec5SDimitry Andric assert(MaskElt >= 0 && MaskElt < 2 * NumOpElts && "Out-of-range mask");
17180b57cec5SDimitry Andric MaskElt = (MaskElt < NumOpElts) ? MaskElt + NumOpElts : MaskElt - NumOpElts;
17195ffd83dbSDimitry Andric NewMask[i] = MaskElt;
17200b57cec5SDimitry Andric }
17215ffd83dbSDimitry Andric setShuffleMask(NewMask);
17220b57cec5SDimitry Andric Op<0>().swap(Op<1>());
17230b57cec5SDimitry Andric }
17240b57cec5SDimitry Andric
isValidOperands(const Value * V1,const Value * V2,ArrayRef<int> Mask)17250b57cec5SDimitry Andric bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
17265ffd83dbSDimitry Andric ArrayRef<int> Mask) {
17275ffd83dbSDimitry Andric // V1 and V2 must be vectors of the same type.
17285ffd83dbSDimitry Andric if (!isa<VectorType>(V1->getType()) || V1->getType() != V2->getType())
17295ffd83dbSDimitry Andric return false;
17305ffd83dbSDimitry Andric
17315ffd83dbSDimitry Andric // Make sure the mask elements make sense.
1732e8d8bef9SDimitry Andric int V1Size =
1733e8d8bef9SDimitry Andric cast<VectorType>(V1->getType())->getElementCount().getKnownMinValue();
17345ffd83dbSDimitry Andric for (int Elem : Mask)
173506c3fb27SDimitry Andric if (Elem != PoisonMaskElem && Elem >= V1Size * 2)
17365ffd83dbSDimitry Andric return false;
17375ffd83dbSDimitry Andric
17385ffd83dbSDimitry Andric if (isa<ScalableVectorType>(V1->getType()))
173906c3fb27SDimitry Andric if ((Mask[0] != 0 && Mask[0] != PoisonMaskElem) || !all_equal(Mask))
17405ffd83dbSDimitry Andric return false;
17415ffd83dbSDimitry Andric
17425ffd83dbSDimitry Andric return true;
17435ffd83dbSDimitry Andric }
17445ffd83dbSDimitry Andric
isValidOperands(const Value * V1,const Value * V2,const Value * Mask)17455ffd83dbSDimitry Andric bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2,
17460b57cec5SDimitry Andric const Value *Mask) {
17470b57cec5SDimitry Andric // V1 and V2 must be vectors of the same type.
17480b57cec5SDimitry Andric if (!V1->getType()->isVectorTy() || V1->getType() != V2->getType())
17490b57cec5SDimitry Andric return false;
17500b57cec5SDimitry Andric
17515ffd83dbSDimitry Andric // Mask must be vector of i32, and must be the same kind of vector as the
17525ffd83dbSDimitry Andric // input vectors
17530b57cec5SDimitry Andric auto *MaskTy = dyn_cast<VectorType>(Mask->getType());
17545ffd83dbSDimitry Andric if (!MaskTy || !MaskTy->getElementType()->isIntegerTy(32) ||
17555ffd83dbSDimitry Andric isa<ScalableVectorType>(MaskTy) != isa<ScalableVectorType>(V1->getType()))
17560b57cec5SDimitry Andric return false;
17570b57cec5SDimitry Andric
17580b57cec5SDimitry Andric // Check to see if Mask is valid.
17590b57cec5SDimitry Andric if (isa<UndefValue>(Mask) || isa<ConstantAggregateZero>(Mask))
17600b57cec5SDimitry Andric return true;
17610b57cec5SDimitry Andric
17620b57cec5SDimitry Andric if (const auto *MV = dyn_cast<ConstantVector>(Mask)) {
1763e8d8bef9SDimitry Andric unsigned V1Size = cast<FixedVectorType>(V1->getType())->getNumElements();
17640b57cec5SDimitry Andric for (Value *Op : MV->operands()) {
17650b57cec5SDimitry Andric if (auto *CI = dyn_cast<ConstantInt>(Op)) {
17660b57cec5SDimitry Andric if (CI->uge(V1Size*2))
17670b57cec5SDimitry Andric return false;
17680b57cec5SDimitry Andric } else if (!isa<UndefValue>(Op)) {
17690b57cec5SDimitry Andric return false;
17700b57cec5SDimitry Andric }
17710b57cec5SDimitry Andric }
17720b57cec5SDimitry Andric return true;
17730b57cec5SDimitry Andric }
17740b57cec5SDimitry Andric
17750b57cec5SDimitry Andric if (const auto *CDS = dyn_cast<ConstantDataSequential>(Mask)) {
1776e8d8bef9SDimitry Andric unsigned V1Size = cast<FixedVectorType>(V1->getType())->getNumElements();
1777e8d8bef9SDimitry Andric for (unsigned i = 0, e = cast<FixedVectorType>(MaskTy)->getNumElements();
1778e8d8bef9SDimitry Andric i != e; ++i)
17790b57cec5SDimitry Andric if (CDS->getElementAsInteger(i) >= V1Size*2)
17800b57cec5SDimitry Andric return false;
17810b57cec5SDimitry Andric return true;
17820b57cec5SDimitry Andric }
17830b57cec5SDimitry Andric
17840b57cec5SDimitry Andric return false;
17850b57cec5SDimitry Andric }
17860b57cec5SDimitry Andric
getShuffleMask(const Constant * Mask,SmallVectorImpl<int> & Result)17870b57cec5SDimitry Andric void ShuffleVectorInst::getShuffleMask(const Constant *Mask,
17880b57cec5SDimitry Andric SmallVectorImpl<int> &Result) {
1789e8d8bef9SDimitry Andric ElementCount EC = cast<VectorType>(Mask->getType())->getElementCount();
1790e8d8bef9SDimitry Andric
17915ffd83dbSDimitry Andric if (isa<ConstantAggregateZero>(Mask)) {
1792e8d8bef9SDimitry Andric Result.resize(EC.getKnownMinValue(), 0);
17935ffd83dbSDimitry Andric return;
17945ffd83dbSDimitry Andric }
1795e8d8bef9SDimitry Andric
1796e8d8bef9SDimitry Andric Result.reserve(EC.getKnownMinValue());
1797e8d8bef9SDimitry Andric
1798e8d8bef9SDimitry Andric if (EC.isScalable()) {
1799e8d8bef9SDimitry Andric assert((isa<ConstantAggregateZero>(Mask) || isa<UndefValue>(Mask)) &&
1800e8d8bef9SDimitry Andric "Scalable vector shuffle mask must be undef or zeroinitializer");
1801e8d8bef9SDimitry Andric int MaskVal = isa<UndefValue>(Mask) ? -1 : 0;
1802e8d8bef9SDimitry Andric for (unsigned I = 0; I < EC.getKnownMinValue(); ++I)
1803e8d8bef9SDimitry Andric Result.emplace_back(MaskVal);
1804e8d8bef9SDimitry Andric return;
1805e8d8bef9SDimitry Andric }
1806e8d8bef9SDimitry Andric
1807e8d8bef9SDimitry Andric unsigned NumElts = EC.getKnownMinValue();
1808e8d8bef9SDimitry Andric
18090b57cec5SDimitry Andric if (auto *CDS = dyn_cast<ConstantDataSequential>(Mask)) {
18100b57cec5SDimitry Andric for (unsigned i = 0; i != NumElts; ++i)
18110b57cec5SDimitry Andric Result.push_back(CDS->getElementAsInteger(i));
18120b57cec5SDimitry Andric return;
18130b57cec5SDimitry Andric }
18140b57cec5SDimitry Andric for (unsigned i = 0; i != NumElts; ++i) {
18150b57cec5SDimitry Andric Constant *C = Mask->getAggregateElement(i);
18160b57cec5SDimitry Andric Result.push_back(isa<UndefValue>(C) ? -1 :
18170b57cec5SDimitry Andric cast<ConstantInt>(C)->getZExtValue());
18180b57cec5SDimitry Andric }
18190b57cec5SDimitry Andric }
18200b57cec5SDimitry Andric
setShuffleMask(ArrayRef<int> Mask)18215ffd83dbSDimitry Andric void ShuffleVectorInst::setShuffleMask(ArrayRef<int> Mask) {
18225ffd83dbSDimitry Andric ShuffleMask.assign(Mask.begin(), Mask.end());
18235ffd83dbSDimitry Andric ShuffleMaskForBitcode = convertShuffleMaskForBitcode(Mask, getType());
18245ffd83dbSDimitry Andric }
1825fe6060f1SDimitry Andric
convertShuffleMaskForBitcode(ArrayRef<int> Mask,Type * ResultTy)18265ffd83dbSDimitry Andric Constant *ShuffleVectorInst::convertShuffleMaskForBitcode(ArrayRef<int> Mask,
18275ffd83dbSDimitry Andric Type *ResultTy) {
18285ffd83dbSDimitry Andric Type *Int32Ty = Type::getInt32Ty(ResultTy->getContext());
18295ffd83dbSDimitry Andric if (isa<ScalableVectorType>(ResultTy)) {
1830bdd1243dSDimitry Andric assert(all_equal(Mask) && "Unexpected shuffle");
18315ffd83dbSDimitry Andric Type *VecTy = VectorType::get(Int32Ty, Mask.size(), true);
18325ffd83dbSDimitry Andric if (Mask[0] == 0)
18335ffd83dbSDimitry Andric return Constant::getNullValue(VecTy);
1834*0fca6ea1SDimitry Andric return PoisonValue::get(VecTy);
18355ffd83dbSDimitry Andric }
18365ffd83dbSDimitry Andric SmallVector<Constant *, 16> MaskConst;
18375ffd83dbSDimitry Andric for (int Elem : Mask) {
183806c3fb27SDimitry Andric if (Elem == PoisonMaskElem)
183906c3fb27SDimitry Andric MaskConst.push_back(PoisonValue::get(Int32Ty));
18405ffd83dbSDimitry Andric else
18415ffd83dbSDimitry Andric MaskConst.push_back(ConstantInt::get(Int32Ty, Elem));
18425ffd83dbSDimitry Andric }
18435ffd83dbSDimitry Andric return ConstantVector::get(MaskConst);
18445ffd83dbSDimitry Andric }
18455ffd83dbSDimitry Andric
isSingleSourceMaskImpl(ArrayRef<int> Mask,int NumOpElts)18460b57cec5SDimitry Andric static bool isSingleSourceMaskImpl(ArrayRef<int> Mask, int NumOpElts) {
18470b57cec5SDimitry Andric assert(!Mask.empty() && "Shuffle mask must contain elements");
18480b57cec5SDimitry Andric bool UsesLHS = false;
18490b57cec5SDimitry Andric bool UsesRHS = false;
1850fe6060f1SDimitry Andric for (int I : Mask) {
1851fe6060f1SDimitry Andric if (I == -1)
18520b57cec5SDimitry Andric continue;
1853fe6060f1SDimitry Andric assert(I >= 0 && I < (NumOpElts * 2) &&
18540b57cec5SDimitry Andric "Out-of-bounds shuffle mask element");
1855fe6060f1SDimitry Andric UsesLHS |= (I < NumOpElts);
1856fe6060f1SDimitry Andric UsesRHS |= (I >= NumOpElts);
18570b57cec5SDimitry Andric if (UsesLHS && UsesRHS)
18580b57cec5SDimitry Andric return false;
18590b57cec5SDimitry Andric }
18605ffd83dbSDimitry Andric // Allow for degenerate case: completely undef mask means neither source is used.
18615ffd83dbSDimitry Andric return UsesLHS || UsesRHS;
18620b57cec5SDimitry Andric }
18630b57cec5SDimitry Andric
isSingleSourceMask(ArrayRef<int> Mask,int NumSrcElts)18645f757f3fSDimitry Andric bool ShuffleVectorInst::isSingleSourceMask(ArrayRef<int> Mask, int NumSrcElts) {
18650b57cec5SDimitry Andric // We don't have vector operand size information, so assume operands are the
18660b57cec5SDimitry Andric // same size as the mask.
18675f757f3fSDimitry Andric return isSingleSourceMaskImpl(Mask, NumSrcElts);
18680b57cec5SDimitry Andric }
18690b57cec5SDimitry Andric
isIdentityMaskImpl(ArrayRef<int> Mask,int NumOpElts)18700b57cec5SDimitry Andric static bool isIdentityMaskImpl(ArrayRef<int> Mask, int NumOpElts) {
18710b57cec5SDimitry Andric if (!isSingleSourceMaskImpl(Mask, NumOpElts))
18720b57cec5SDimitry Andric return false;
18730b57cec5SDimitry Andric for (int i = 0, NumMaskElts = Mask.size(); i < NumMaskElts; ++i) {
18740b57cec5SDimitry Andric if (Mask[i] == -1)
18750b57cec5SDimitry Andric continue;
18760b57cec5SDimitry Andric if (Mask[i] != i && Mask[i] != (NumOpElts + i))
18770b57cec5SDimitry Andric return false;
18780b57cec5SDimitry Andric }
18790b57cec5SDimitry Andric return true;
18800b57cec5SDimitry Andric }
18810b57cec5SDimitry Andric
isIdentityMask(ArrayRef<int> Mask,int NumSrcElts)18825f757f3fSDimitry Andric bool ShuffleVectorInst::isIdentityMask(ArrayRef<int> Mask, int NumSrcElts) {
18835f757f3fSDimitry Andric if (Mask.size() != static_cast<unsigned>(NumSrcElts))
18845f757f3fSDimitry Andric return false;
18850b57cec5SDimitry Andric // We don't have vector operand size information, so assume operands are the
18860b57cec5SDimitry Andric // same size as the mask.
18875f757f3fSDimitry Andric return isIdentityMaskImpl(Mask, NumSrcElts);
18880b57cec5SDimitry Andric }
18890b57cec5SDimitry Andric
isReverseMask(ArrayRef<int> Mask,int NumSrcElts)18905f757f3fSDimitry Andric bool ShuffleVectorInst::isReverseMask(ArrayRef<int> Mask, int NumSrcElts) {
18915f757f3fSDimitry Andric if (Mask.size() != static_cast<unsigned>(NumSrcElts))
18925f757f3fSDimitry Andric return false;
18935f757f3fSDimitry Andric if (!isSingleSourceMask(Mask, NumSrcElts))
18940b57cec5SDimitry Andric return false;
189581ad6265SDimitry Andric
189681ad6265SDimitry Andric // The number of elements in the mask must be at least 2.
18975f757f3fSDimitry Andric if (NumSrcElts < 2)
189881ad6265SDimitry Andric return false;
189981ad6265SDimitry Andric
19005f757f3fSDimitry Andric for (int I = 0, E = Mask.size(); I < E; ++I) {
19015f757f3fSDimitry Andric if (Mask[I] == -1)
19020b57cec5SDimitry Andric continue;
19035f757f3fSDimitry Andric if (Mask[I] != (NumSrcElts - 1 - I) &&
19045f757f3fSDimitry Andric Mask[I] != (NumSrcElts + NumSrcElts - 1 - I))
19050b57cec5SDimitry Andric return false;
19060b57cec5SDimitry Andric }
19070b57cec5SDimitry Andric return true;
19080b57cec5SDimitry Andric }
19090b57cec5SDimitry Andric
isZeroEltSplatMask(ArrayRef<int> Mask,int NumSrcElts)19105f757f3fSDimitry Andric bool ShuffleVectorInst::isZeroEltSplatMask(ArrayRef<int> Mask, int NumSrcElts) {
19115f757f3fSDimitry Andric if (Mask.size() != static_cast<unsigned>(NumSrcElts))
19120b57cec5SDimitry Andric return false;
19135f757f3fSDimitry Andric if (!isSingleSourceMask(Mask, NumSrcElts))
19145f757f3fSDimitry Andric return false;
19155f757f3fSDimitry Andric for (int I = 0, E = Mask.size(); I < E; ++I) {
19165f757f3fSDimitry Andric if (Mask[I] == -1)
19170b57cec5SDimitry Andric continue;
19185f757f3fSDimitry Andric if (Mask[I] != 0 && Mask[I] != NumSrcElts)
19190b57cec5SDimitry Andric return false;
19200b57cec5SDimitry Andric }
19210b57cec5SDimitry Andric return true;
19220b57cec5SDimitry Andric }
19230b57cec5SDimitry Andric
isSelectMask(ArrayRef<int> Mask,int NumSrcElts)19245f757f3fSDimitry Andric bool ShuffleVectorInst::isSelectMask(ArrayRef<int> Mask, int NumSrcElts) {
19255f757f3fSDimitry Andric if (Mask.size() != static_cast<unsigned>(NumSrcElts))
19265f757f3fSDimitry Andric return false;
19270b57cec5SDimitry Andric // Select is differentiated from identity. It requires using both sources.
19285f757f3fSDimitry Andric if (isSingleSourceMask(Mask, NumSrcElts))
19290b57cec5SDimitry Andric return false;
19305f757f3fSDimitry Andric for (int I = 0, E = Mask.size(); I < E; ++I) {
19315f757f3fSDimitry Andric if (Mask[I] == -1)
19320b57cec5SDimitry Andric continue;
19335f757f3fSDimitry Andric if (Mask[I] != I && Mask[I] != (NumSrcElts + I))
19340b57cec5SDimitry Andric return false;
19350b57cec5SDimitry Andric }
19360b57cec5SDimitry Andric return true;
19370b57cec5SDimitry Andric }
19380b57cec5SDimitry Andric
isTransposeMask(ArrayRef<int> Mask,int NumSrcElts)19395f757f3fSDimitry Andric bool ShuffleVectorInst::isTransposeMask(ArrayRef<int> Mask, int NumSrcElts) {
19400b57cec5SDimitry Andric // Example masks that will return true:
19410b57cec5SDimitry Andric // v1 = <a, b, c, d>
19420b57cec5SDimitry Andric // v2 = <e, f, g, h>
19430b57cec5SDimitry Andric // trn1 = shufflevector v1, v2 <0, 4, 2, 6> = <a, e, c, g>
19440b57cec5SDimitry Andric // trn2 = shufflevector v1, v2 <1, 5, 3, 7> = <b, f, d, h>
19450b57cec5SDimitry Andric
19465f757f3fSDimitry Andric if (Mask.size() != static_cast<unsigned>(NumSrcElts))
19475f757f3fSDimitry Andric return false;
19480b57cec5SDimitry Andric // 1. The number of elements in the mask must be a power-of-2 and at least 2.
19495f757f3fSDimitry Andric int Sz = Mask.size();
19505f757f3fSDimitry Andric if (Sz < 2 || !isPowerOf2_32(Sz))
19510b57cec5SDimitry Andric return false;
19520b57cec5SDimitry Andric
19530b57cec5SDimitry Andric // 2. The first element of the mask must be either a 0 or a 1.
19540b57cec5SDimitry Andric if (Mask[0] != 0 && Mask[0] != 1)
19550b57cec5SDimitry Andric return false;
19560b57cec5SDimitry Andric
19570b57cec5SDimitry Andric // 3. The difference between the first 2 elements must be equal to the
19580b57cec5SDimitry Andric // number of elements in the mask.
19595f757f3fSDimitry Andric if ((Mask[1] - Mask[0]) != NumSrcElts)
19600b57cec5SDimitry Andric return false;
19610b57cec5SDimitry Andric
19620b57cec5SDimitry Andric // 4. The difference between consecutive even-numbered and odd-numbered
19630b57cec5SDimitry Andric // elements must be equal to 2.
19645f757f3fSDimitry Andric for (int I = 2; I < Sz; ++I) {
19655f757f3fSDimitry Andric int MaskEltVal = Mask[I];
19660b57cec5SDimitry Andric if (MaskEltVal == -1)
19670b57cec5SDimitry Andric return false;
19685f757f3fSDimitry Andric int MaskEltPrevVal = Mask[I - 2];
19690b57cec5SDimitry Andric if (MaskEltVal - MaskEltPrevVal != 2)
19700b57cec5SDimitry Andric return false;
19710b57cec5SDimitry Andric }
19720b57cec5SDimitry Andric return true;
19730b57cec5SDimitry Andric }
19740b57cec5SDimitry Andric
isSpliceMask(ArrayRef<int> Mask,int NumSrcElts,int & Index)19755f757f3fSDimitry Andric bool ShuffleVectorInst::isSpliceMask(ArrayRef<int> Mask, int NumSrcElts,
19765f757f3fSDimitry Andric int &Index) {
19775f757f3fSDimitry Andric if (Mask.size() != static_cast<unsigned>(NumSrcElts))
19785f757f3fSDimitry Andric return false;
1979bdd1243dSDimitry Andric // Example: shufflevector <4 x n> A, <4 x n> B, <1,2,3,4>
1980bdd1243dSDimitry Andric int StartIndex = -1;
1981bdd1243dSDimitry Andric for (int I = 0, E = Mask.size(); I != E; ++I) {
1982bdd1243dSDimitry Andric int MaskEltVal = Mask[I];
1983bdd1243dSDimitry Andric if (MaskEltVal == -1)
1984bdd1243dSDimitry Andric continue;
1985bdd1243dSDimitry Andric
1986bdd1243dSDimitry Andric if (StartIndex == -1) {
1987bdd1243dSDimitry Andric // Don't support a StartIndex that begins in the second input, or if the
1988bdd1243dSDimitry Andric // first non-undef index would access below the StartIndex.
19895f757f3fSDimitry Andric if (MaskEltVal < I || NumSrcElts <= (MaskEltVal - I))
1990bdd1243dSDimitry Andric return false;
1991bdd1243dSDimitry Andric
1992bdd1243dSDimitry Andric StartIndex = MaskEltVal - I;
1993bdd1243dSDimitry Andric continue;
1994bdd1243dSDimitry Andric }
1995bdd1243dSDimitry Andric
1996bdd1243dSDimitry Andric // Splice is sequential starting from StartIndex.
1997bdd1243dSDimitry Andric if (MaskEltVal != (StartIndex + I))
1998bdd1243dSDimitry Andric return false;
1999bdd1243dSDimitry Andric }
2000bdd1243dSDimitry Andric
2001bdd1243dSDimitry Andric if (StartIndex == -1)
2002bdd1243dSDimitry Andric return false;
2003bdd1243dSDimitry Andric
2004bdd1243dSDimitry Andric // NOTE: This accepts StartIndex == 0 (COPY).
2005bdd1243dSDimitry Andric Index = StartIndex;
2006bdd1243dSDimitry Andric return true;
2007bdd1243dSDimitry Andric }
2008bdd1243dSDimitry Andric
isExtractSubvectorMask(ArrayRef<int> Mask,int NumSrcElts,int & Index)20090b57cec5SDimitry Andric bool ShuffleVectorInst::isExtractSubvectorMask(ArrayRef<int> Mask,
20100b57cec5SDimitry Andric int NumSrcElts, int &Index) {
20110b57cec5SDimitry Andric // Must extract from a single source.
20120b57cec5SDimitry Andric if (!isSingleSourceMaskImpl(Mask, NumSrcElts))
20130b57cec5SDimitry Andric return false;
20140b57cec5SDimitry Andric
20150b57cec5SDimitry Andric // Must be smaller (else this is an Identity shuffle).
20160b57cec5SDimitry Andric if (NumSrcElts <= (int)Mask.size())
20170b57cec5SDimitry Andric return false;
20180b57cec5SDimitry Andric
20190b57cec5SDimitry Andric // Find start of extraction, accounting that we may start with an UNDEF.
20200b57cec5SDimitry Andric int SubIndex = -1;
20210b57cec5SDimitry Andric for (int i = 0, e = Mask.size(); i != e; ++i) {
20220b57cec5SDimitry Andric int M = Mask[i];
20230b57cec5SDimitry Andric if (M < 0)
20240b57cec5SDimitry Andric continue;
20250b57cec5SDimitry Andric int Offset = (M % NumSrcElts) - i;
20260b57cec5SDimitry Andric if (0 <= SubIndex && SubIndex != Offset)
20270b57cec5SDimitry Andric return false;
20280b57cec5SDimitry Andric SubIndex = Offset;
20290b57cec5SDimitry Andric }
20300b57cec5SDimitry Andric
2031480093f4SDimitry Andric if (0 <= SubIndex && SubIndex + (int)Mask.size() <= NumSrcElts) {
20320b57cec5SDimitry Andric Index = SubIndex;
20330b57cec5SDimitry Andric return true;
20340b57cec5SDimitry Andric }
20350b57cec5SDimitry Andric return false;
20360b57cec5SDimitry Andric }
20370b57cec5SDimitry Andric
isInsertSubvectorMask(ArrayRef<int> Mask,int NumSrcElts,int & NumSubElts,int & Index)2038349cc55cSDimitry Andric bool ShuffleVectorInst::isInsertSubvectorMask(ArrayRef<int> Mask,
2039349cc55cSDimitry Andric int NumSrcElts, int &NumSubElts,
2040349cc55cSDimitry Andric int &Index) {
2041349cc55cSDimitry Andric int NumMaskElts = Mask.size();
2042349cc55cSDimitry Andric
2043349cc55cSDimitry Andric // Don't try to match if we're shuffling to a smaller size.
2044349cc55cSDimitry Andric if (NumMaskElts < NumSrcElts)
2045349cc55cSDimitry Andric return false;
2046349cc55cSDimitry Andric
2047349cc55cSDimitry Andric // TODO: We don't recognize self-insertion/widening.
2048349cc55cSDimitry Andric if (isSingleSourceMaskImpl(Mask, NumSrcElts))
2049349cc55cSDimitry Andric return false;
2050349cc55cSDimitry Andric
2051349cc55cSDimitry Andric // Determine which mask elements are attributed to which source.
2052349cc55cSDimitry Andric APInt UndefElts = APInt::getZero(NumMaskElts);
2053349cc55cSDimitry Andric APInt Src0Elts = APInt::getZero(NumMaskElts);
2054349cc55cSDimitry Andric APInt Src1Elts = APInt::getZero(NumMaskElts);
2055349cc55cSDimitry Andric bool Src0Identity = true;
2056349cc55cSDimitry Andric bool Src1Identity = true;
2057349cc55cSDimitry Andric
2058349cc55cSDimitry Andric for (int i = 0; i != NumMaskElts; ++i) {
2059349cc55cSDimitry Andric int M = Mask[i];
2060349cc55cSDimitry Andric if (M < 0) {
2061349cc55cSDimitry Andric UndefElts.setBit(i);
2062349cc55cSDimitry Andric continue;
2063349cc55cSDimitry Andric }
2064349cc55cSDimitry Andric if (M < NumSrcElts) {
2065349cc55cSDimitry Andric Src0Elts.setBit(i);
2066349cc55cSDimitry Andric Src0Identity &= (M == i);
2067349cc55cSDimitry Andric continue;
2068349cc55cSDimitry Andric }
2069349cc55cSDimitry Andric Src1Elts.setBit(i);
2070349cc55cSDimitry Andric Src1Identity &= (M == (i + NumSrcElts));
2071349cc55cSDimitry Andric }
2072349cc55cSDimitry Andric assert((Src0Elts | Src1Elts | UndefElts).isAllOnes() &&
2073349cc55cSDimitry Andric "unknown shuffle elements");
2074349cc55cSDimitry Andric assert(!Src0Elts.isZero() && !Src1Elts.isZero() &&
2075349cc55cSDimitry Andric "2-source shuffle not found");
2076349cc55cSDimitry Andric
2077349cc55cSDimitry Andric // Determine lo/hi span ranges.
2078349cc55cSDimitry Andric // TODO: How should we handle undefs at the start of subvector insertions?
207906c3fb27SDimitry Andric int Src0Lo = Src0Elts.countr_zero();
208006c3fb27SDimitry Andric int Src1Lo = Src1Elts.countr_zero();
208106c3fb27SDimitry Andric int Src0Hi = NumMaskElts - Src0Elts.countl_zero();
208206c3fb27SDimitry Andric int Src1Hi = NumMaskElts - Src1Elts.countl_zero();
2083349cc55cSDimitry Andric
2084349cc55cSDimitry Andric // If src0 is in place, see if the src1 elements is inplace within its own
2085349cc55cSDimitry Andric // span.
2086349cc55cSDimitry Andric if (Src0Identity) {
2087349cc55cSDimitry Andric int NumSub1Elts = Src1Hi - Src1Lo;
2088349cc55cSDimitry Andric ArrayRef<int> Sub1Mask = Mask.slice(Src1Lo, NumSub1Elts);
2089349cc55cSDimitry Andric if (isIdentityMaskImpl(Sub1Mask, NumSrcElts)) {
2090349cc55cSDimitry Andric NumSubElts = NumSub1Elts;
2091349cc55cSDimitry Andric Index = Src1Lo;
2092349cc55cSDimitry Andric return true;
2093349cc55cSDimitry Andric }
2094349cc55cSDimitry Andric }
2095349cc55cSDimitry Andric
2096349cc55cSDimitry Andric // If src1 is in place, see if the src0 elements is inplace within its own
2097349cc55cSDimitry Andric // span.
2098349cc55cSDimitry Andric if (Src1Identity) {
2099349cc55cSDimitry Andric int NumSub0Elts = Src0Hi - Src0Lo;
2100349cc55cSDimitry Andric ArrayRef<int> Sub0Mask = Mask.slice(Src0Lo, NumSub0Elts);
2101349cc55cSDimitry Andric if (isIdentityMaskImpl(Sub0Mask, NumSrcElts)) {
2102349cc55cSDimitry Andric NumSubElts = NumSub0Elts;
2103349cc55cSDimitry Andric Index = Src0Lo;
2104349cc55cSDimitry Andric return true;
2105349cc55cSDimitry Andric }
2106349cc55cSDimitry Andric }
2107349cc55cSDimitry Andric
2108349cc55cSDimitry Andric return false;
2109349cc55cSDimitry Andric }
2110349cc55cSDimitry Andric
isIdentityWithPadding() const21110b57cec5SDimitry Andric bool ShuffleVectorInst::isIdentityWithPadding() const {
2112e8d8bef9SDimitry Andric // FIXME: Not currently possible to express a shuffle mask for a scalable
2113e8d8bef9SDimitry Andric // vector for this case.
2114e8d8bef9SDimitry Andric if (isa<ScalableVectorType>(getType()))
2115e8d8bef9SDimitry Andric return false;
2116e8d8bef9SDimitry Andric
2117e8d8bef9SDimitry Andric int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
2118e8d8bef9SDimitry Andric int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
21190b57cec5SDimitry Andric if (NumMaskElts <= NumOpElts)
21200b57cec5SDimitry Andric return false;
21210b57cec5SDimitry Andric
21220b57cec5SDimitry Andric // The first part of the mask must choose elements from exactly 1 source op.
21235ffd83dbSDimitry Andric ArrayRef<int> Mask = getShuffleMask();
21240b57cec5SDimitry Andric if (!isIdentityMaskImpl(Mask, NumOpElts))
21250b57cec5SDimitry Andric return false;
21260b57cec5SDimitry Andric
21270b57cec5SDimitry Andric // All extending must be with undef elements.
21280b57cec5SDimitry Andric for (int i = NumOpElts; i < NumMaskElts; ++i)
21290b57cec5SDimitry Andric if (Mask[i] != -1)
21300b57cec5SDimitry Andric return false;
21310b57cec5SDimitry Andric
21320b57cec5SDimitry Andric return true;
21330b57cec5SDimitry Andric }
21340b57cec5SDimitry Andric
isIdentityWithExtract() const21350b57cec5SDimitry Andric bool ShuffleVectorInst::isIdentityWithExtract() const {
21365ffd83dbSDimitry Andric // FIXME: Not currently possible to express a shuffle mask for a scalable
2137e8d8bef9SDimitry Andric // vector for this case.
21385ffd83dbSDimitry Andric if (isa<ScalableVectorType>(getType()))
21395ffd83dbSDimitry Andric return false;
21405ffd83dbSDimitry Andric
21415ffd83dbSDimitry Andric int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
21425ffd83dbSDimitry Andric int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
21430b57cec5SDimitry Andric if (NumMaskElts >= NumOpElts)
21440b57cec5SDimitry Andric return false;
21450b57cec5SDimitry Andric
21460b57cec5SDimitry Andric return isIdentityMaskImpl(getShuffleMask(), NumOpElts);
21470b57cec5SDimitry Andric }
21480b57cec5SDimitry Andric
isConcat() const21490b57cec5SDimitry Andric bool ShuffleVectorInst::isConcat() const {
21500b57cec5SDimitry Andric // Vector concatenation is differentiated from identity with padding.
21515f757f3fSDimitry Andric if (isa<UndefValue>(Op<0>()) || isa<UndefValue>(Op<1>()))
21520b57cec5SDimitry Andric return false;
21530b57cec5SDimitry Andric
2154e8d8bef9SDimitry Andric // FIXME: Not currently possible to express a shuffle mask for a scalable
2155e8d8bef9SDimitry Andric // vector for this case.
2156e8d8bef9SDimitry Andric if (isa<ScalableVectorType>(getType()))
2157e8d8bef9SDimitry Andric return false;
2158e8d8bef9SDimitry Andric
2159e8d8bef9SDimitry Andric int NumOpElts = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
2160e8d8bef9SDimitry Andric int NumMaskElts = cast<FixedVectorType>(getType())->getNumElements();
21610b57cec5SDimitry Andric if (NumMaskElts != NumOpElts * 2)
21620b57cec5SDimitry Andric return false;
21630b57cec5SDimitry Andric
21640b57cec5SDimitry Andric // Use the mask length rather than the operands' vector lengths here. We
21650b57cec5SDimitry Andric // already know that the shuffle returns a vector twice as long as the inputs,
21660b57cec5SDimitry Andric // and neither of the inputs are undef vectors. If the mask picks consecutive
21670b57cec5SDimitry Andric // elements from both inputs, then this is a concatenation of the inputs.
21680b57cec5SDimitry Andric return isIdentityMaskImpl(getShuffleMask(), NumMaskElts);
21690b57cec5SDimitry Andric }
21700b57cec5SDimitry Andric
isReplicationMaskWithParams(ArrayRef<int> Mask,int ReplicationFactor,int VF)2171349cc55cSDimitry Andric static bool isReplicationMaskWithParams(ArrayRef<int> Mask,
2172349cc55cSDimitry Andric int ReplicationFactor, int VF) {
2173349cc55cSDimitry Andric assert(Mask.size() == (unsigned)ReplicationFactor * VF &&
2174349cc55cSDimitry Andric "Unexpected mask size.");
2175349cc55cSDimitry Andric
21765f757f3fSDimitry Andric for (int CurrElt : seq(VF)) {
2177349cc55cSDimitry Andric ArrayRef<int> CurrSubMask = Mask.take_front(ReplicationFactor);
2178349cc55cSDimitry Andric assert(CurrSubMask.size() == (unsigned)ReplicationFactor &&
2179349cc55cSDimitry Andric "Run out of mask?");
2180349cc55cSDimitry Andric Mask = Mask.drop_front(ReplicationFactor);
2181349cc55cSDimitry Andric if (!all_of(CurrSubMask, [CurrElt](int MaskElt) {
218206c3fb27SDimitry Andric return MaskElt == PoisonMaskElem || MaskElt == CurrElt;
2183349cc55cSDimitry Andric }))
2184349cc55cSDimitry Andric return false;
2185349cc55cSDimitry Andric }
2186349cc55cSDimitry Andric assert(Mask.empty() && "Did not consume the whole mask?");
2187349cc55cSDimitry Andric
2188349cc55cSDimitry Andric return true;
2189349cc55cSDimitry Andric }
2190349cc55cSDimitry Andric
isReplicationMask(ArrayRef<int> Mask,int & ReplicationFactor,int & VF)2191349cc55cSDimitry Andric bool ShuffleVectorInst::isReplicationMask(ArrayRef<int> Mask,
2192349cc55cSDimitry Andric int &ReplicationFactor, int &VF) {
2193349cc55cSDimitry Andric // undef-less case is trivial.
219406c3fb27SDimitry Andric if (!llvm::is_contained(Mask, PoisonMaskElem)) {
2195349cc55cSDimitry Andric ReplicationFactor =
2196349cc55cSDimitry Andric Mask.take_while([](int MaskElt) { return MaskElt == 0; }).size();
2197349cc55cSDimitry Andric if (ReplicationFactor == 0 || Mask.size() % ReplicationFactor != 0)
2198349cc55cSDimitry Andric return false;
2199349cc55cSDimitry Andric VF = Mask.size() / ReplicationFactor;
2200349cc55cSDimitry Andric return isReplicationMaskWithParams(Mask, ReplicationFactor, VF);
2201349cc55cSDimitry Andric }
2202349cc55cSDimitry Andric
2203349cc55cSDimitry Andric // However, if the mask contains undef's, we have to enumerate possible tuples
2204349cc55cSDimitry Andric // and pick one. There are bounds on replication factor: [1, mask size]
2205349cc55cSDimitry Andric // (where RF=1 is an identity shuffle, RF=mask size is a broadcast shuffle)
2206349cc55cSDimitry Andric // Additionally, mask size is a replication factor multiplied by vector size,
2207349cc55cSDimitry Andric // which further significantly reduces the search space.
2208349cc55cSDimitry Andric
22094824e7fdSDimitry Andric // Before doing that, let's perform basic correctness checking first.
2210349cc55cSDimitry Andric int Largest = -1;
2211349cc55cSDimitry Andric for (int MaskElt : Mask) {
221206c3fb27SDimitry Andric if (MaskElt == PoisonMaskElem)
2213349cc55cSDimitry Andric continue;
2214349cc55cSDimitry Andric // Elements must be in non-decreasing order.
2215349cc55cSDimitry Andric if (MaskElt < Largest)
2216349cc55cSDimitry Andric return false;
2217349cc55cSDimitry Andric Largest = std::max(Largest, MaskElt);
2218349cc55cSDimitry Andric }
2219349cc55cSDimitry Andric
2220349cc55cSDimitry Andric // Prefer larger replication factor if all else equal.
2221349cc55cSDimitry Andric for (int PossibleReplicationFactor :
2222349cc55cSDimitry Andric reverse(seq_inclusive<unsigned>(1, Mask.size()))) {
2223349cc55cSDimitry Andric if (Mask.size() % PossibleReplicationFactor != 0)
2224349cc55cSDimitry Andric continue;
2225349cc55cSDimitry Andric int PossibleVF = Mask.size() / PossibleReplicationFactor;
2226349cc55cSDimitry Andric if (!isReplicationMaskWithParams(Mask, PossibleReplicationFactor,
2227349cc55cSDimitry Andric PossibleVF))
2228349cc55cSDimitry Andric continue;
2229349cc55cSDimitry Andric ReplicationFactor = PossibleReplicationFactor;
2230349cc55cSDimitry Andric VF = PossibleVF;
2231349cc55cSDimitry Andric return true;
2232349cc55cSDimitry Andric }
2233349cc55cSDimitry Andric
2234349cc55cSDimitry Andric return false;
2235349cc55cSDimitry Andric }
2236349cc55cSDimitry Andric
isReplicationMask(int & ReplicationFactor,int & VF) const2237349cc55cSDimitry Andric bool ShuffleVectorInst::isReplicationMask(int &ReplicationFactor,
2238349cc55cSDimitry Andric int &VF) const {
2239349cc55cSDimitry Andric // Not possible to express a shuffle mask for a scalable vector for this
2240349cc55cSDimitry Andric // case.
2241349cc55cSDimitry Andric if (isa<ScalableVectorType>(getType()))
2242349cc55cSDimitry Andric return false;
2243349cc55cSDimitry Andric
2244349cc55cSDimitry Andric VF = cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
2245349cc55cSDimitry Andric if (ShuffleMask.size() % VF != 0)
2246349cc55cSDimitry Andric return false;
2247349cc55cSDimitry Andric ReplicationFactor = ShuffleMask.size() / VF;
2248349cc55cSDimitry Andric
2249349cc55cSDimitry Andric return isReplicationMaskWithParams(ShuffleMask, ReplicationFactor, VF);
2250349cc55cSDimitry Andric }
2251349cc55cSDimitry Andric
isOneUseSingleSourceMask(ArrayRef<int> Mask,int VF)2252bdd1243dSDimitry Andric bool ShuffleVectorInst::isOneUseSingleSourceMask(ArrayRef<int> Mask, int VF) {
2253bdd1243dSDimitry Andric if (VF <= 0 || Mask.size() < static_cast<unsigned>(VF) ||
2254bdd1243dSDimitry Andric Mask.size() % VF != 0)
2255bdd1243dSDimitry Andric return false;
2256bdd1243dSDimitry Andric for (unsigned K = 0, Sz = Mask.size(); K < Sz; K += VF) {
2257bdd1243dSDimitry Andric ArrayRef<int> SubMask = Mask.slice(K, VF);
225806c3fb27SDimitry Andric if (all_of(SubMask, [](int Idx) { return Idx == PoisonMaskElem; }))
2259bdd1243dSDimitry Andric continue;
2260bdd1243dSDimitry Andric SmallBitVector Used(VF, false);
22615f757f3fSDimitry Andric for (int Idx : SubMask) {
226206c3fb27SDimitry Andric if (Idx != PoisonMaskElem && Idx < VF)
2263bdd1243dSDimitry Andric Used.set(Idx);
22645f757f3fSDimitry Andric }
2265bdd1243dSDimitry Andric if (!Used.all())
2266bdd1243dSDimitry Andric return false;
2267bdd1243dSDimitry Andric }
2268bdd1243dSDimitry Andric return true;
2269bdd1243dSDimitry Andric }
2270bdd1243dSDimitry Andric
2271bdd1243dSDimitry Andric /// Return true if this shuffle mask is a replication mask.
isOneUseSingleSourceMask(int VF) const2272bdd1243dSDimitry Andric bool ShuffleVectorInst::isOneUseSingleSourceMask(int VF) const {
2273bdd1243dSDimitry Andric // Not possible to express a shuffle mask for a scalable vector for this
2274bdd1243dSDimitry Andric // case.
2275bdd1243dSDimitry Andric if (isa<ScalableVectorType>(getType()))
2276bdd1243dSDimitry Andric return false;
22775f757f3fSDimitry Andric if (!isSingleSourceMask(ShuffleMask, VF))
2278bdd1243dSDimitry Andric return false;
2279bdd1243dSDimitry Andric
2280bdd1243dSDimitry Andric return isOneUseSingleSourceMask(ShuffleMask, VF);
2281bdd1243dSDimitry Andric }
2282bdd1243dSDimitry Andric
isInterleave(unsigned Factor)228306c3fb27SDimitry Andric bool ShuffleVectorInst::isInterleave(unsigned Factor) {
228406c3fb27SDimitry Andric FixedVectorType *OpTy = dyn_cast<FixedVectorType>(getOperand(0)->getType());
228506c3fb27SDimitry Andric // shuffle_vector can only interleave fixed length vectors - for scalable
2286*0fca6ea1SDimitry Andric // vectors, see the @llvm.vector.interleave2 intrinsic
228706c3fb27SDimitry Andric if (!OpTy)
228806c3fb27SDimitry Andric return false;
228906c3fb27SDimitry Andric unsigned OpNumElts = OpTy->getNumElements();
229006c3fb27SDimitry Andric
229106c3fb27SDimitry Andric return isInterleaveMask(ShuffleMask, Factor, OpNumElts * 2);
229206c3fb27SDimitry Andric }
229306c3fb27SDimitry Andric
isInterleaveMask(ArrayRef<int> Mask,unsigned Factor,unsigned NumInputElts,SmallVectorImpl<unsigned> & StartIndexes)229406c3fb27SDimitry Andric bool ShuffleVectorInst::isInterleaveMask(
229506c3fb27SDimitry Andric ArrayRef<int> Mask, unsigned Factor, unsigned NumInputElts,
229606c3fb27SDimitry Andric SmallVectorImpl<unsigned> &StartIndexes) {
229706c3fb27SDimitry Andric unsigned NumElts = Mask.size();
229806c3fb27SDimitry Andric if (NumElts % Factor)
229906c3fb27SDimitry Andric return false;
230006c3fb27SDimitry Andric
230106c3fb27SDimitry Andric unsigned LaneLen = NumElts / Factor;
230206c3fb27SDimitry Andric if (!isPowerOf2_32(LaneLen))
230306c3fb27SDimitry Andric return false;
230406c3fb27SDimitry Andric
230506c3fb27SDimitry Andric StartIndexes.resize(Factor);
230606c3fb27SDimitry Andric
230706c3fb27SDimitry Andric // Check whether each element matches the general interleaved rule.
230806c3fb27SDimitry Andric // Ignore undef elements, as long as the defined elements match the rule.
230906c3fb27SDimitry Andric // Outer loop processes all factors (x, y, z in the above example)
231006c3fb27SDimitry Andric unsigned I = 0, J;
231106c3fb27SDimitry Andric for (; I < Factor; I++) {
231206c3fb27SDimitry Andric unsigned SavedLaneValue;
231306c3fb27SDimitry Andric unsigned SavedNoUndefs = 0;
231406c3fb27SDimitry Andric
231506c3fb27SDimitry Andric // Inner loop processes consecutive accesses (x, x+1... in the example)
231606c3fb27SDimitry Andric for (J = 0; J < LaneLen - 1; J++) {
231706c3fb27SDimitry Andric // Lane computes x's position in the Mask
231806c3fb27SDimitry Andric unsigned Lane = J * Factor + I;
231906c3fb27SDimitry Andric unsigned NextLane = Lane + Factor;
232006c3fb27SDimitry Andric int LaneValue = Mask[Lane];
232106c3fb27SDimitry Andric int NextLaneValue = Mask[NextLane];
232206c3fb27SDimitry Andric
232306c3fb27SDimitry Andric // If both are defined, values must be sequential
232406c3fb27SDimitry Andric if (LaneValue >= 0 && NextLaneValue >= 0 &&
232506c3fb27SDimitry Andric LaneValue + 1 != NextLaneValue)
232606c3fb27SDimitry Andric break;
232706c3fb27SDimitry Andric
232806c3fb27SDimitry Andric // If the next value is undef, save the current one as reference
232906c3fb27SDimitry Andric if (LaneValue >= 0 && NextLaneValue < 0) {
233006c3fb27SDimitry Andric SavedLaneValue = LaneValue;
233106c3fb27SDimitry Andric SavedNoUndefs = 1;
233206c3fb27SDimitry Andric }
233306c3fb27SDimitry Andric
233406c3fb27SDimitry Andric // Undefs are allowed, but defined elements must still be consecutive:
233506c3fb27SDimitry Andric // i.e.: x,..., undef,..., x + 2,..., undef,..., undef,..., x + 5, ....
233606c3fb27SDimitry Andric // Verify this by storing the last non-undef followed by an undef
233706c3fb27SDimitry Andric // Check that following non-undef masks are incremented with the
233806c3fb27SDimitry Andric // corresponding distance.
233906c3fb27SDimitry Andric if (SavedNoUndefs > 0 && LaneValue < 0) {
234006c3fb27SDimitry Andric SavedNoUndefs++;
234106c3fb27SDimitry Andric if (NextLaneValue >= 0 &&
234206c3fb27SDimitry Andric SavedLaneValue + SavedNoUndefs != (unsigned)NextLaneValue)
234306c3fb27SDimitry Andric break;
234406c3fb27SDimitry Andric }
234506c3fb27SDimitry Andric }
234606c3fb27SDimitry Andric
234706c3fb27SDimitry Andric if (J < LaneLen - 1)
234806c3fb27SDimitry Andric return false;
234906c3fb27SDimitry Andric
235006c3fb27SDimitry Andric int StartMask = 0;
235106c3fb27SDimitry Andric if (Mask[I] >= 0) {
235206c3fb27SDimitry Andric // Check that the start of the I range (J=0) is greater than 0
235306c3fb27SDimitry Andric StartMask = Mask[I];
235406c3fb27SDimitry Andric } else if (Mask[(LaneLen - 1) * Factor + I] >= 0) {
235506c3fb27SDimitry Andric // StartMask defined by the last value in lane
235606c3fb27SDimitry Andric StartMask = Mask[(LaneLen - 1) * Factor + I] - J;
235706c3fb27SDimitry Andric } else if (SavedNoUndefs > 0) {
235806c3fb27SDimitry Andric // StartMask defined by some non-zero value in the j loop
235906c3fb27SDimitry Andric StartMask = SavedLaneValue - (LaneLen - 1 - SavedNoUndefs);
236006c3fb27SDimitry Andric }
236106c3fb27SDimitry Andric // else StartMask remains set to 0, i.e. all elements are undefs
236206c3fb27SDimitry Andric
236306c3fb27SDimitry Andric if (StartMask < 0)
236406c3fb27SDimitry Andric return false;
236506c3fb27SDimitry Andric // We must stay within the vectors; This case can happen with undefs.
236606c3fb27SDimitry Andric if (StartMask + LaneLen > NumInputElts)
236706c3fb27SDimitry Andric return false;
236806c3fb27SDimitry Andric
236906c3fb27SDimitry Andric StartIndexes[I] = StartMask;
237006c3fb27SDimitry Andric }
237106c3fb27SDimitry Andric
237206c3fb27SDimitry Andric return true;
237306c3fb27SDimitry Andric }
237406c3fb27SDimitry Andric
2375*0fca6ea1SDimitry Andric /// Check if the mask is a DE-interleave mask of the given factor
2376*0fca6ea1SDimitry Andric /// \p Factor like:
2377*0fca6ea1SDimitry Andric /// <Index, Index+Factor, ..., Index+(NumElts-1)*Factor>
isDeInterleaveMaskOfFactor(ArrayRef<int> Mask,unsigned Factor,unsigned & Index)2378*0fca6ea1SDimitry Andric bool ShuffleVectorInst::isDeInterleaveMaskOfFactor(ArrayRef<int> Mask,
2379*0fca6ea1SDimitry Andric unsigned Factor,
2380*0fca6ea1SDimitry Andric unsigned &Index) {
2381*0fca6ea1SDimitry Andric // Check all potential start indices from 0 to (Factor - 1).
2382*0fca6ea1SDimitry Andric for (unsigned Idx = 0; Idx < Factor; Idx++) {
2383*0fca6ea1SDimitry Andric unsigned I = 0;
2384*0fca6ea1SDimitry Andric
2385*0fca6ea1SDimitry Andric // Check that elements are in ascending order by Factor. Ignore undef
2386*0fca6ea1SDimitry Andric // elements.
2387*0fca6ea1SDimitry Andric for (; I < Mask.size(); I++)
2388*0fca6ea1SDimitry Andric if (Mask[I] >= 0 && static_cast<unsigned>(Mask[I]) != Idx + I * Factor)
2389*0fca6ea1SDimitry Andric break;
2390*0fca6ea1SDimitry Andric
2391*0fca6ea1SDimitry Andric if (I == Mask.size()) {
2392*0fca6ea1SDimitry Andric Index = Idx;
2393*0fca6ea1SDimitry Andric return true;
2394*0fca6ea1SDimitry Andric }
2395*0fca6ea1SDimitry Andric }
2396*0fca6ea1SDimitry Andric
2397*0fca6ea1SDimitry Andric return false;
2398*0fca6ea1SDimitry Andric }
2399*0fca6ea1SDimitry Andric
24005f757f3fSDimitry Andric /// Try to lower a vector shuffle as a bit rotation.
24015f757f3fSDimitry Andric ///
24025f757f3fSDimitry Andric /// Look for a repeated rotation pattern in each sub group.
24035f757f3fSDimitry Andric /// Returns an element-wise left bit rotation amount or -1 if failed.
matchShuffleAsBitRotate(ArrayRef<int> Mask,int NumSubElts)24045f757f3fSDimitry Andric static int matchShuffleAsBitRotate(ArrayRef<int> Mask, int NumSubElts) {
24055f757f3fSDimitry Andric int NumElts = Mask.size();
24065f757f3fSDimitry Andric assert((NumElts % NumSubElts) == 0 && "Illegal shuffle mask");
24075f757f3fSDimitry Andric
24085f757f3fSDimitry Andric int RotateAmt = -1;
24095f757f3fSDimitry Andric for (int i = 0; i != NumElts; i += NumSubElts) {
24105f757f3fSDimitry Andric for (int j = 0; j != NumSubElts; ++j) {
24115f757f3fSDimitry Andric int M = Mask[i + j];
24125f757f3fSDimitry Andric if (M < 0)
24135f757f3fSDimitry Andric continue;
24145f757f3fSDimitry Andric if (M < i || M >= i + NumSubElts)
24155f757f3fSDimitry Andric return -1;
24165f757f3fSDimitry Andric int Offset = (NumSubElts - (M - (i + j))) % NumSubElts;
24175f757f3fSDimitry Andric if (0 <= RotateAmt && Offset != RotateAmt)
24185f757f3fSDimitry Andric return -1;
24195f757f3fSDimitry Andric RotateAmt = Offset;
24205f757f3fSDimitry Andric }
24215f757f3fSDimitry Andric }
24225f757f3fSDimitry Andric return RotateAmt;
24235f757f3fSDimitry Andric }
24245f757f3fSDimitry Andric
isBitRotateMask(ArrayRef<int> Mask,unsigned EltSizeInBits,unsigned MinSubElts,unsigned MaxSubElts,unsigned & NumSubElts,unsigned & RotateAmt)24255f757f3fSDimitry Andric bool ShuffleVectorInst::isBitRotateMask(
24265f757f3fSDimitry Andric ArrayRef<int> Mask, unsigned EltSizeInBits, unsigned MinSubElts,
24275f757f3fSDimitry Andric unsigned MaxSubElts, unsigned &NumSubElts, unsigned &RotateAmt) {
24285f757f3fSDimitry Andric for (NumSubElts = MinSubElts; NumSubElts <= MaxSubElts; NumSubElts *= 2) {
24295f757f3fSDimitry Andric int EltRotateAmt = matchShuffleAsBitRotate(Mask, NumSubElts);
24305f757f3fSDimitry Andric if (EltRotateAmt < 0)
24315f757f3fSDimitry Andric continue;
24325f757f3fSDimitry Andric RotateAmt = EltRotateAmt * EltSizeInBits;
24335f757f3fSDimitry Andric return true;
24345f757f3fSDimitry Andric }
24355f757f3fSDimitry Andric
24365f757f3fSDimitry Andric return false;
24375f757f3fSDimitry Andric }
24385f757f3fSDimitry Andric
24390b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
24400b57cec5SDimitry Andric // InsertValueInst Class
24410b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
24420b57cec5SDimitry Andric
init(Value * Agg,Value * Val,ArrayRef<unsigned> Idxs,const Twine & Name)24430b57cec5SDimitry Andric void InsertValueInst::init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
24440b57cec5SDimitry Andric const Twine &Name) {
24450b57cec5SDimitry Andric assert(getNumOperands() == 2 && "NumOperands not initialized?");
24460b57cec5SDimitry Andric
24470b57cec5SDimitry Andric // There's no fundamental reason why we require at least one index
24480b57cec5SDimitry Andric // (other than weirdness with &*IdxBegin being invalid; see
24490b57cec5SDimitry Andric // getelementptr's init routine for example). But there's no
24500b57cec5SDimitry Andric // present need to support it.
24510b57cec5SDimitry Andric assert(!Idxs.empty() && "InsertValueInst must have at least one index");
24520b57cec5SDimitry Andric
24530b57cec5SDimitry Andric assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs) ==
24540b57cec5SDimitry Andric Val->getType() && "Inserted value must match indexed type!");
24550b57cec5SDimitry Andric Op<0>() = Agg;
24560b57cec5SDimitry Andric Op<1>() = Val;
24570b57cec5SDimitry Andric
24580b57cec5SDimitry Andric Indices.append(Idxs.begin(), Idxs.end());
24590b57cec5SDimitry Andric setName(Name);
24600b57cec5SDimitry Andric }
24610b57cec5SDimitry Andric
InsertValueInst(const InsertValueInst & IVI)24620b57cec5SDimitry Andric InsertValueInst::InsertValueInst(const InsertValueInst &IVI)
24630b57cec5SDimitry Andric : Instruction(IVI.getType(), InsertValue,
24640b57cec5SDimitry Andric OperandTraits<InsertValueInst>::op_begin(this), 2),
24650b57cec5SDimitry Andric Indices(IVI.Indices) {
24660b57cec5SDimitry Andric Op<0>() = IVI.getOperand(0);
24670b57cec5SDimitry Andric Op<1>() = IVI.getOperand(1);
24680b57cec5SDimitry Andric SubclassOptionalData = IVI.SubclassOptionalData;
24690b57cec5SDimitry Andric }
24700b57cec5SDimitry Andric
24710b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
24720b57cec5SDimitry Andric // ExtractValueInst Class
24730b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
24740b57cec5SDimitry Andric
init(ArrayRef<unsigned> Idxs,const Twine & Name)24750b57cec5SDimitry Andric void ExtractValueInst::init(ArrayRef<unsigned> Idxs, const Twine &Name) {
24760b57cec5SDimitry Andric assert(getNumOperands() == 1 && "NumOperands not initialized?");
24770b57cec5SDimitry Andric
24780b57cec5SDimitry Andric // There's no fundamental reason why we require at least one index.
24790b57cec5SDimitry Andric // But there's no present need to support it.
24800b57cec5SDimitry Andric assert(!Idxs.empty() && "ExtractValueInst must have at least one index");
24810b57cec5SDimitry Andric
24820b57cec5SDimitry Andric Indices.append(Idxs.begin(), Idxs.end());
24830b57cec5SDimitry Andric setName(Name);
24840b57cec5SDimitry Andric }
24850b57cec5SDimitry Andric
ExtractValueInst(const ExtractValueInst & EVI)24860b57cec5SDimitry Andric ExtractValueInst::ExtractValueInst(const ExtractValueInst &EVI)
24870b57cec5SDimitry Andric : UnaryInstruction(EVI.getType(), ExtractValue, EVI.getOperand(0)),
24880b57cec5SDimitry Andric Indices(EVI.Indices) {
24890b57cec5SDimitry Andric SubclassOptionalData = EVI.SubclassOptionalData;
24900b57cec5SDimitry Andric }
24910b57cec5SDimitry Andric
24920b57cec5SDimitry Andric // getIndexedType - Returns the type of the element that would be extracted
24930b57cec5SDimitry Andric // with an extractvalue instruction with the specified parameters.
24940b57cec5SDimitry Andric //
24950b57cec5SDimitry Andric // A null type is returned if the indices are invalid for the specified
24960b57cec5SDimitry Andric // pointer type.
24970b57cec5SDimitry Andric //
getIndexedType(Type * Agg,ArrayRef<unsigned> Idxs)24980b57cec5SDimitry Andric Type *ExtractValueInst::getIndexedType(Type *Agg,
24990b57cec5SDimitry Andric ArrayRef<unsigned> Idxs) {
25000b57cec5SDimitry Andric for (unsigned Index : Idxs) {
25010b57cec5SDimitry Andric // We can't use CompositeType::indexValid(Index) here.
25020b57cec5SDimitry Andric // indexValid() always returns true for arrays because getelementptr allows
25030b57cec5SDimitry Andric // out-of-bounds indices. Since we don't allow those for extractvalue and
25040b57cec5SDimitry Andric // insertvalue we need to check array indexing manually.
25050b57cec5SDimitry Andric // Since the only other types we can index into are struct types it's just
25060b57cec5SDimitry Andric // as easy to check those manually as well.
25070b57cec5SDimitry Andric if (ArrayType *AT = dyn_cast<ArrayType>(Agg)) {
25080b57cec5SDimitry Andric if (Index >= AT->getNumElements())
25090b57cec5SDimitry Andric return nullptr;
25105ffd83dbSDimitry Andric Agg = AT->getElementType();
25110b57cec5SDimitry Andric } else if (StructType *ST = dyn_cast<StructType>(Agg)) {
25120b57cec5SDimitry Andric if (Index >= ST->getNumElements())
25130b57cec5SDimitry Andric return nullptr;
25145ffd83dbSDimitry Andric Agg = ST->getElementType(Index);
25150b57cec5SDimitry Andric } else {
25160b57cec5SDimitry Andric // Not a valid type to index into.
25170b57cec5SDimitry Andric return nullptr;
25180b57cec5SDimitry Andric }
25190b57cec5SDimitry Andric }
25200b57cec5SDimitry Andric return const_cast<Type*>(Agg);
25210b57cec5SDimitry Andric }
25220b57cec5SDimitry Andric
25230b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
25240b57cec5SDimitry Andric // UnaryOperator Class
25250b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
25260b57cec5SDimitry Andric
UnaryOperator(UnaryOps iType,Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)2527*0fca6ea1SDimitry Andric UnaryOperator::UnaryOperator(UnaryOps iType, Value *S, Type *Ty,
2528*0fca6ea1SDimitry Andric const Twine &Name, InsertPosition InsertBefore)
25290b57cec5SDimitry Andric : UnaryInstruction(Ty, iType, S, InsertBefore) {
25300b57cec5SDimitry Andric Op<0>() = S;
25310b57cec5SDimitry Andric setName(Name);
25320b57cec5SDimitry Andric AssertOK();
25330b57cec5SDimitry Andric }
25340b57cec5SDimitry Andric
Create(UnaryOps Op,Value * S,const Twine & Name,InsertPosition InsertBefore)2535*0fca6ea1SDimitry Andric UnaryOperator *UnaryOperator::Create(UnaryOps Op, Value *S, const Twine &Name,
2536*0fca6ea1SDimitry Andric InsertPosition InsertBefore) {
25370b57cec5SDimitry Andric return new UnaryOperator(Op, S, S->getType(), Name, InsertBefore);
25380b57cec5SDimitry Andric }
25390b57cec5SDimitry Andric
AssertOK()25400b57cec5SDimitry Andric void UnaryOperator::AssertOK() {
25410b57cec5SDimitry Andric Value *LHS = getOperand(0);
25420b57cec5SDimitry Andric (void)LHS; // Silence warnings.
25430b57cec5SDimitry Andric #ifndef NDEBUG
25440b57cec5SDimitry Andric switch (getOpcode()) {
25450b57cec5SDimitry Andric case FNeg:
25460b57cec5SDimitry Andric assert(getType() == LHS->getType() &&
25470b57cec5SDimitry Andric "Unary operation should return same type as operand!");
25480b57cec5SDimitry Andric assert(getType()->isFPOrFPVectorTy() &&
25490b57cec5SDimitry Andric "Tried to create a floating-point operation on a "
25500b57cec5SDimitry Andric "non-floating-point type!");
25510b57cec5SDimitry Andric break;
25520b57cec5SDimitry Andric default: llvm_unreachable("Invalid opcode provided");
25530b57cec5SDimitry Andric }
25540b57cec5SDimitry Andric #endif
25550b57cec5SDimitry Andric }
25560b57cec5SDimitry Andric
25570b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
25580b57cec5SDimitry Andric // BinaryOperator Class
25590b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
25600b57cec5SDimitry Andric
BinaryOperator(BinaryOps iType,Value * S1,Value * S2,Type * Ty,const Twine & Name,InsertPosition InsertBefore)2561*0fca6ea1SDimitry Andric BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty,
2562*0fca6ea1SDimitry Andric const Twine &Name, InsertPosition InsertBefore)
2563*0fca6ea1SDimitry Andric : Instruction(Ty, iType, OperandTraits<BinaryOperator>::op_begin(this),
2564*0fca6ea1SDimitry Andric OperandTraits<BinaryOperator>::operands(this), InsertBefore) {
25650b57cec5SDimitry Andric Op<0>() = S1;
25660b57cec5SDimitry Andric Op<1>() = S2;
25670b57cec5SDimitry Andric setName(Name);
25680b57cec5SDimitry Andric AssertOK();
25690b57cec5SDimitry Andric }
25700b57cec5SDimitry Andric
AssertOK()25710b57cec5SDimitry Andric void BinaryOperator::AssertOK() {
25720b57cec5SDimitry Andric Value *LHS = getOperand(0), *RHS = getOperand(1);
25730b57cec5SDimitry Andric (void)LHS; (void)RHS; // Silence warnings.
25740b57cec5SDimitry Andric assert(LHS->getType() == RHS->getType() &&
25750b57cec5SDimitry Andric "Binary operator operand types must match!");
25760b57cec5SDimitry Andric #ifndef NDEBUG
25770b57cec5SDimitry Andric switch (getOpcode()) {
25780b57cec5SDimitry Andric case Add: case Sub:
25790b57cec5SDimitry Andric case Mul:
25800b57cec5SDimitry Andric assert(getType() == LHS->getType() &&
25810b57cec5SDimitry Andric "Arithmetic operation should return same type as operands!");
25820b57cec5SDimitry Andric assert(getType()->isIntOrIntVectorTy() &&
25830b57cec5SDimitry Andric "Tried to create an integer operation on a non-integer type!");
25840b57cec5SDimitry Andric break;
25850b57cec5SDimitry Andric case FAdd: case FSub:
25860b57cec5SDimitry Andric case FMul:
25870b57cec5SDimitry Andric assert(getType() == LHS->getType() &&
25880b57cec5SDimitry Andric "Arithmetic operation should return same type as operands!");
25890b57cec5SDimitry Andric assert(getType()->isFPOrFPVectorTy() &&
25900b57cec5SDimitry Andric "Tried to create a floating-point operation on a "
25910b57cec5SDimitry Andric "non-floating-point type!");
25920b57cec5SDimitry Andric break;
25930b57cec5SDimitry Andric case UDiv:
25940b57cec5SDimitry Andric case SDiv:
25950b57cec5SDimitry Andric assert(getType() == LHS->getType() &&
25960b57cec5SDimitry Andric "Arithmetic operation should return same type as operands!");
25970b57cec5SDimitry Andric assert(getType()->isIntOrIntVectorTy() &&
25980b57cec5SDimitry Andric "Incorrect operand type (not integer) for S/UDIV");
25990b57cec5SDimitry Andric break;
26000b57cec5SDimitry Andric case FDiv:
26010b57cec5SDimitry Andric assert(getType() == LHS->getType() &&
26020b57cec5SDimitry Andric "Arithmetic operation should return same type as operands!");
26030b57cec5SDimitry Andric assert(getType()->isFPOrFPVectorTy() &&
26040b57cec5SDimitry Andric "Incorrect operand type (not floating point) for FDIV");
26050b57cec5SDimitry Andric break;
26060b57cec5SDimitry Andric case URem:
26070b57cec5SDimitry Andric case SRem:
26080b57cec5SDimitry Andric assert(getType() == LHS->getType() &&
26090b57cec5SDimitry Andric "Arithmetic operation should return same type as operands!");
26100b57cec5SDimitry Andric assert(getType()->isIntOrIntVectorTy() &&
26110b57cec5SDimitry Andric "Incorrect operand type (not integer) for S/UREM");
26120b57cec5SDimitry Andric break;
26130b57cec5SDimitry Andric case FRem:
26140b57cec5SDimitry Andric assert(getType() == LHS->getType() &&
26150b57cec5SDimitry Andric "Arithmetic operation should return same type as operands!");
26160b57cec5SDimitry Andric assert(getType()->isFPOrFPVectorTy() &&
26170b57cec5SDimitry Andric "Incorrect operand type (not floating point) for FREM");
26180b57cec5SDimitry Andric break;
26190b57cec5SDimitry Andric case Shl:
26200b57cec5SDimitry Andric case LShr:
26210b57cec5SDimitry Andric case AShr:
26220b57cec5SDimitry Andric assert(getType() == LHS->getType() &&
26230b57cec5SDimitry Andric "Shift operation should return same type as operands!");
26240b57cec5SDimitry Andric assert(getType()->isIntOrIntVectorTy() &&
26250b57cec5SDimitry Andric "Tried to create a shift operation on a non-integral type!");
26260b57cec5SDimitry Andric break;
26270b57cec5SDimitry Andric case And: case Or:
26280b57cec5SDimitry Andric case Xor:
26290b57cec5SDimitry Andric assert(getType() == LHS->getType() &&
26300b57cec5SDimitry Andric "Logical operation should return same type as operands!");
26310b57cec5SDimitry Andric assert(getType()->isIntOrIntVectorTy() &&
26320b57cec5SDimitry Andric "Tried to create a logical operation on a non-integral type!");
26330b57cec5SDimitry Andric break;
26340b57cec5SDimitry Andric default: llvm_unreachable("Invalid opcode provided");
26350b57cec5SDimitry Andric }
26360b57cec5SDimitry Andric #endif
26370b57cec5SDimitry Andric }
26380b57cec5SDimitry Andric
Create(BinaryOps Op,Value * S1,Value * S2,const Twine & Name,InsertPosition InsertBefore)26390b57cec5SDimitry Andric BinaryOperator *BinaryOperator::Create(BinaryOps Op, Value *S1, Value *S2,
26400b57cec5SDimitry Andric const Twine &Name,
2641*0fca6ea1SDimitry Andric InsertPosition InsertBefore) {
26420b57cec5SDimitry Andric assert(S1->getType() == S2->getType() &&
26430b57cec5SDimitry Andric "Cannot create binary operator with two operands of differing type!");
26440b57cec5SDimitry Andric return new BinaryOperator(Op, S1, S2, S1->getType(), Name, InsertBefore);
26450b57cec5SDimitry Andric }
26460b57cec5SDimitry Andric
CreateNeg(Value * Op,const Twine & Name,InsertPosition InsertBefore)26470b57cec5SDimitry Andric BinaryOperator *BinaryOperator::CreateNeg(Value *Op, const Twine &Name,
2648*0fca6ea1SDimitry Andric InsertPosition InsertBefore) {
264906c3fb27SDimitry Andric Value *Zero = ConstantInt::get(Op->getType(), 0);
2650*0fca6ea1SDimitry Andric return new BinaryOperator(Instruction::Sub, Zero, Op, Op->getType(), Name,
2651*0fca6ea1SDimitry Andric InsertBefore);
26520b57cec5SDimitry Andric }
26530b57cec5SDimitry Andric
CreateNSWNeg(Value * Op,const Twine & Name,InsertPosition InsertBefore)26540b57cec5SDimitry Andric BinaryOperator *BinaryOperator::CreateNSWNeg(Value *Op, const Twine &Name,
2655*0fca6ea1SDimitry Andric InsertPosition InsertBefore) {
265606c3fb27SDimitry Andric Value *Zero = ConstantInt::get(Op->getType(), 0);
265706c3fb27SDimitry Andric return BinaryOperator::CreateNSWSub(Zero, Op, Name, InsertBefore);
26580b57cec5SDimitry Andric }
26590b57cec5SDimitry Andric
CreateNot(Value * Op,const Twine & Name,InsertPosition InsertBefore)26600b57cec5SDimitry Andric BinaryOperator *BinaryOperator::CreateNot(Value *Op, const Twine &Name,
2661*0fca6ea1SDimitry Andric InsertPosition InsertBefore) {
26620b57cec5SDimitry Andric Constant *C = Constant::getAllOnesValue(Op->getType());
26630b57cec5SDimitry Andric return new BinaryOperator(Instruction::Xor, Op, C,
26640b57cec5SDimitry Andric Op->getType(), Name, InsertBefore);
26650b57cec5SDimitry Andric }
26660b57cec5SDimitry Andric
26670b57cec5SDimitry Andric // Exchange the two operands to this instruction. This instruction is safe to
26680b57cec5SDimitry Andric // use on any binary instruction and does not modify the semantics of the
26690b57cec5SDimitry Andric // instruction. If the instruction is order-dependent (SetLT f.e.), the opcode
26700b57cec5SDimitry Andric // is changed.
swapOperands()26710b57cec5SDimitry Andric bool BinaryOperator::swapOperands() {
26720b57cec5SDimitry Andric if (!isCommutative())
26730b57cec5SDimitry Andric return true; // Can't commute operands
26740b57cec5SDimitry Andric Op<0>().swap(Op<1>());
26750b57cec5SDimitry Andric return false;
26760b57cec5SDimitry Andric }
26770b57cec5SDimitry Andric
26780b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
26790b57cec5SDimitry Andric // FPMathOperator Class
26800b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
26810b57cec5SDimitry Andric
getFPAccuracy() const26820b57cec5SDimitry Andric float FPMathOperator::getFPAccuracy() const {
26830b57cec5SDimitry Andric const MDNode *MD =
26840b57cec5SDimitry Andric cast<Instruction>(this)->getMetadata(LLVMContext::MD_fpmath);
26850b57cec5SDimitry Andric if (!MD)
26860b57cec5SDimitry Andric return 0.0;
26870b57cec5SDimitry Andric ConstantFP *Accuracy = mdconst::extract<ConstantFP>(MD->getOperand(0));
26880b57cec5SDimitry Andric return Accuracy->getValueAPF().convertToFloat();
26890b57cec5SDimitry Andric }
26900b57cec5SDimitry Andric
26910b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
26920b57cec5SDimitry Andric // CastInst Class
26930b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
26940b57cec5SDimitry Andric
26950b57cec5SDimitry Andric // Just determine if this cast only deals with integral->integral conversion.
isIntegerCast() const26960b57cec5SDimitry Andric bool CastInst::isIntegerCast() const {
26970b57cec5SDimitry Andric switch (getOpcode()) {
26980b57cec5SDimitry Andric default: return false;
26990b57cec5SDimitry Andric case Instruction::ZExt:
27000b57cec5SDimitry Andric case Instruction::SExt:
27010b57cec5SDimitry Andric case Instruction::Trunc:
27020b57cec5SDimitry Andric return true;
27030b57cec5SDimitry Andric case Instruction::BitCast:
27040b57cec5SDimitry Andric return getOperand(0)->getType()->isIntegerTy() &&
27050b57cec5SDimitry Andric getType()->isIntegerTy();
27060b57cec5SDimitry Andric }
27070b57cec5SDimitry Andric }
27080b57cec5SDimitry Andric
27090b57cec5SDimitry Andric /// This function determines if the CastInst does not require any bits to be
27100b57cec5SDimitry Andric /// changed in order to effect the cast. Essentially, it identifies cases where
27110b57cec5SDimitry Andric /// no code gen is necessary for the cast, hence the name no-op cast. For
27120b57cec5SDimitry Andric /// example, the following are all no-op casts:
27130b57cec5SDimitry Andric /// # bitcast i32* %x to i8*
27140b57cec5SDimitry Andric /// # bitcast <2 x i32> %x to <4 x i16>
27150b57cec5SDimitry Andric /// # ptrtoint i32* %x to i32 ; on 32-bit plaforms only
27160b57cec5SDimitry Andric /// Determine if the described cast is a no-op.
isNoopCast(Instruction::CastOps Opcode,Type * SrcTy,Type * DestTy,const DataLayout & DL)27170b57cec5SDimitry Andric bool CastInst::isNoopCast(Instruction::CastOps Opcode,
27180b57cec5SDimitry Andric Type *SrcTy,
27190b57cec5SDimitry Andric Type *DestTy,
27200b57cec5SDimitry Andric const DataLayout &DL) {
2721e8d8bef9SDimitry Andric assert(castIsValid(Opcode, SrcTy, DestTy) && "method precondition");
27220b57cec5SDimitry Andric switch (Opcode) {
27230b57cec5SDimitry Andric default: llvm_unreachable("Invalid CastOp");
27240b57cec5SDimitry Andric case Instruction::Trunc:
27250b57cec5SDimitry Andric case Instruction::ZExt:
27260b57cec5SDimitry Andric case Instruction::SExt:
27270b57cec5SDimitry Andric case Instruction::FPTrunc:
27280b57cec5SDimitry Andric case Instruction::FPExt:
27290b57cec5SDimitry Andric case Instruction::UIToFP:
27300b57cec5SDimitry Andric case Instruction::SIToFP:
27310b57cec5SDimitry Andric case Instruction::FPToUI:
27320b57cec5SDimitry Andric case Instruction::FPToSI:
27330b57cec5SDimitry Andric case Instruction::AddrSpaceCast:
27340b57cec5SDimitry Andric // TODO: Target informations may give a more accurate answer here.
27350b57cec5SDimitry Andric return false;
27360b57cec5SDimitry Andric case Instruction::BitCast:
27370b57cec5SDimitry Andric return true; // BitCast never modifies bits.
27380b57cec5SDimitry Andric case Instruction::PtrToInt:
27390b57cec5SDimitry Andric return DL.getIntPtrType(SrcTy)->getScalarSizeInBits() ==
27400b57cec5SDimitry Andric DestTy->getScalarSizeInBits();
27410b57cec5SDimitry Andric case Instruction::IntToPtr:
27420b57cec5SDimitry Andric return DL.getIntPtrType(DestTy)->getScalarSizeInBits() ==
27430b57cec5SDimitry Andric SrcTy->getScalarSizeInBits();
27440b57cec5SDimitry Andric }
27450b57cec5SDimitry Andric }
27460b57cec5SDimitry Andric
isNoopCast(const DataLayout & DL) const27470b57cec5SDimitry Andric bool CastInst::isNoopCast(const DataLayout &DL) const {
27480b57cec5SDimitry Andric return isNoopCast(getOpcode(), getOperand(0)->getType(), getType(), DL);
27490b57cec5SDimitry Andric }
27500b57cec5SDimitry Andric
27510b57cec5SDimitry Andric /// This function determines if a pair of casts can be eliminated and what
27520b57cec5SDimitry Andric /// opcode should be used in the elimination. This assumes that there are two
27530b57cec5SDimitry Andric /// instructions like this:
27540b57cec5SDimitry Andric /// * %F = firstOpcode SrcTy %x to MidTy
27550b57cec5SDimitry Andric /// * %S = secondOpcode MidTy %F to DstTy
27560b57cec5SDimitry Andric /// The function returns a resultOpcode so these two casts can be replaced with:
27570b57cec5SDimitry Andric /// * %Replacement = resultOpcode %SrcTy %x to DstTy
27580b57cec5SDimitry Andric /// If no such cast is permitted, the function returns 0.
isEliminableCastPair(Instruction::CastOps firstOp,Instruction::CastOps secondOp,Type * SrcTy,Type * MidTy,Type * DstTy,Type * SrcIntPtrTy,Type * MidIntPtrTy,Type * DstIntPtrTy)27590b57cec5SDimitry Andric unsigned CastInst::isEliminableCastPair(
27600b57cec5SDimitry Andric Instruction::CastOps firstOp, Instruction::CastOps secondOp,
27610b57cec5SDimitry Andric Type *SrcTy, Type *MidTy, Type *DstTy, Type *SrcIntPtrTy, Type *MidIntPtrTy,
27620b57cec5SDimitry Andric Type *DstIntPtrTy) {
27630b57cec5SDimitry Andric // Define the 144 possibilities for these two cast instructions. The values
27640b57cec5SDimitry Andric // in this matrix determine what to do in a given situation and select the
27650b57cec5SDimitry Andric // case in the switch below. The rows correspond to firstOp, the columns
27660b57cec5SDimitry Andric // correspond to secondOp. In looking at the table below, keep in mind
27670b57cec5SDimitry Andric // the following cast properties:
27680b57cec5SDimitry Andric //
27690b57cec5SDimitry Andric // Size Compare Source Destination
27700b57cec5SDimitry Andric // Operator Src ? Size Type Sign Type Sign
27710b57cec5SDimitry Andric // -------- ------------ ------------------- ---------------------
27720b57cec5SDimitry Andric // TRUNC > Integer Any Integral Any
27730b57cec5SDimitry Andric // ZEXT < Integral Unsigned Integer Any
27740b57cec5SDimitry Andric // SEXT < Integral Signed Integer Any
27750b57cec5SDimitry Andric // FPTOUI n/a FloatPt n/a Integral Unsigned
27760b57cec5SDimitry Andric // FPTOSI n/a FloatPt n/a Integral Signed
27770b57cec5SDimitry Andric // UITOFP n/a Integral Unsigned FloatPt n/a
27780b57cec5SDimitry Andric // SITOFP n/a Integral Signed FloatPt n/a
27790b57cec5SDimitry Andric // FPTRUNC > FloatPt n/a FloatPt n/a
27800b57cec5SDimitry Andric // FPEXT < FloatPt n/a FloatPt n/a
27810b57cec5SDimitry Andric // PTRTOINT n/a Pointer n/a Integral Unsigned
27820b57cec5SDimitry Andric // INTTOPTR n/a Integral Unsigned Pointer n/a
27830b57cec5SDimitry Andric // BITCAST = FirstClass n/a FirstClass n/a
27840b57cec5SDimitry Andric // ADDRSPCST n/a Pointer n/a Pointer n/a
27850b57cec5SDimitry Andric //
27860b57cec5SDimitry Andric // NOTE: some transforms are safe, but we consider them to be non-profitable.
27870b57cec5SDimitry Andric // For example, we could merge "fptoui double to i32" + "zext i32 to i64",
27880b57cec5SDimitry Andric // into "fptoui double to i64", but this loses information about the range
27890b57cec5SDimitry Andric // of the produced value (we no longer know the top-part is all zeros).
27900b57cec5SDimitry Andric // Further this conversion is often much more expensive for typical hardware,
27910b57cec5SDimitry Andric // and causes issues when building libgcc. We disallow fptosi+sext for the
27920b57cec5SDimitry Andric // same reason.
27930b57cec5SDimitry Andric const unsigned numCastOps =
27940b57cec5SDimitry Andric Instruction::CastOpsEnd - Instruction::CastOpsBegin;
27950b57cec5SDimitry Andric static const uint8_t CastResults[numCastOps][numCastOps] = {
27960b57cec5SDimitry Andric // T F F U S F F P I B A -+
27970b57cec5SDimitry Andric // R Z S P P I I T P 2 N T S |
27980b57cec5SDimitry Andric // U E E 2 2 2 2 R E I T C C +- secondOp
27990b57cec5SDimitry Andric // N X X U S F F N X N 2 V V |
28000b57cec5SDimitry Andric // C T T I I P P C T T P T T -+
28010b57cec5SDimitry Andric { 1, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // Trunc -+
28020b57cec5SDimitry Andric { 8, 1, 9,99,99, 2,17,99,99,99, 2, 3, 0}, // ZExt |
28030b57cec5SDimitry Andric { 8, 0, 1,99,99, 0, 2,99,99,99, 0, 3, 0}, // SExt |
28040b57cec5SDimitry Andric { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // FPToUI |
28050b57cec5SDimitry Andric { 0, 0, 0,99,99, 0, 0,99,99,99, 0, 3, 0}, // FPToSI |
28060b57cec5SDimitry Andric { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // UIToFP +- firstOp
28070b57cec5SDimitry Andric { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // SIToFP |
28080b57cec5SDimitry Andric { 99,99,99, 0, 0,99,99, 0, 0,99,99, 4, 0}, // FPTrunc |
28090b57cec5SDimitry Andric { 99,99,99, 2, 2,99,99, 8, 2,99,99, 4, 0}, // FPExt |
28100b57cec5SDimitry Andric { 1, 0, 0,99,99, 0, 0,99,99,99, 7, 3, 0}, // PtrToInt |
28110b57cec5SDimitry Andric { 99,99,99,99,99,99,99,99,99,11,99,15, 0}, // IntToPtr |
2812*0fca6ea1SDimitry Andric { 5, 5, 5, 0, 0, 5, 5, 0, 0,16, 5, 1,14}, // BitCast |
28130b57cec5SDimitry Andric { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13,12}, // AddrSpaceCast -+
28140b57cec5SDimitry Andric };
28150b57cec5SDimitry Andric
28160b57cec5SDimitry Andric // TODO: This logic could be encoded into the table above and handled in the
28170b57cec5SDimitry Andric // switch below.
28180b57cec5SDimitry Andric // If either of the casts are a bitcast from scalar to vector, disallow the
28190b57cec5SDimitry Andric // merging. However, any pair of bitcasts are allowed.
28200b57cec5SDimitry Andric bool IsFirstBitcast = (firstOp == Instruction::BitCast);
28210b57cec5SDimitry Andric bool IsSecondBitcast = (secondOp == Instruction::BitCast);
28220b57cec5SDimitry Andric bool AreBothBitcasts = IsFirstBitcast && IsSecondBitcast;
28230b57cec5SDimitry Andric
28240b57cec5SDimitry Andric // Check if any of the casts convert scalars <-> vectors.
28250b57cec5SDimitry Andric if ((IsFirstBitcast && isa<VectorType>(SrcTy) != isa<VectorType>(MidTy)) ||
28260b57cec5SDimitry Andric (IsSecondBitcast && isa<VectorType>(MidTy) != isa<VectorType>(DstTy)))
28270b57cec5SDimitry Andric if (!AreBothBitcasts)
28280b57cec5SDimitry Andric return 0;
28290b57cec5SDimitry Andric
28300b57cec5SDimitry Andric int ElimCase = CastResults[firstOp-Instruction::CastOpsBegin]
28310b57cec5SDimitry Andric [secondOp-Instruction::CastOpsBegin];
28320b57cec5SDimitry Andric switch (ElimCase) {
28330b57cec5SDimitry Andric case 0:
28340b57cec5SDimitry Andric // Categorically disallowed.
28350b57cec5SDimitry Andric return 0;
28360b57cec5SDimitry Andric case 1:
28370b57cec5SDimitry Andric // Allowed, use first cast's opcode.
28380b57cec5SDimitry Andric return firstOp;
28390b57cec5SDimitry Andric case 2:
28400b57cec5SDimitry Andric // Allowed, use second cast's opcode.
28410b57cec5SDimitry Andric return secondOp;
28420b57cec5SDimitry Andric case 3:
28430b57cec5SDimitry Andric // No-op cast in second op implies firstOp as long as the DestTy
28440b57cec5SDimitry Andric // is integer and we are not converting between a vector and a
28450b57cec5SDimitry Andric // non-vector type.
28460b57cec5SDimitry Andric if (!SrcTy->isVectorTy() && DstTy->isIntegerTy())
28470b57cec5SDimitry Andric return firstOp;
28480b57cec5SDimitry Andric return 0;
28490b57cec5SDimitry Andric case 4:
28500b57cec5SDimitry Andric // No-op cast in second op implies firstOp as long as the DestTy
28517a6dacacSDimitry Andric // matches MidTy.
28527a6dacacSDimitry Andric if (DstTy == MidTy)
28530b57cec5SDimitry Andric return firstOp;
28540b57cec5SDimitry Andric return 0;
28550b57cec5SDimitry Andric case 5:
28560b57cec5SDimitry Andric // No-op cast in first op implies secondOp as long as the SrcTy
28570b57cec5SDimitry Andric // is an integer.
28580b57cec5SDimitry Andric if (SrcTy->isIntegerTy())
28590b57cec5SDimitry Andric return secondOp;
28600b57cec5SDimitry Andric return 0;
28610b57cec5SDimitry Andric case 7: {
2862fe6060f1SDimitry Andric // Disable inttoptr/ptrtoint optimization if enabled.
2863fe6060f1SDimitry Andric if (DisableI2pP2iOpt)
2864fe6060f1SDimitry Andric return 0;
2865fe6060f1SDimitry Andric
28660b57cec5SDimitry Andric // Cannot simplify if address spaces are different!
28670b57cec5SDimitry Andric if (SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace())
28680b57cec5SDimitry Andric return 0;
28690b57cec5SDimitry Andric
28700b57cec5SDimitry Andric unsigned MidSize = MidTy->getScalarSizeInBits();
28710b57cec5SDimitry Andric // We can still fold this without knowing the actual sizes as long we
28720b57cec5SDimitry Andric // know that the intermediate pointer is the largest possible
28730b57cec5SDimitry Andric // pointer size.
28740b57cec5SDimitry Andric // FIXME: Is this always true?
28750b57cec5SDimitry Andric if (MidSize == 64)
28760b57cec5SDimitry Andric return Instruction::BitCast;
28770b57cec5SDimitry Andric
28780b57cec5SDimitry Andric // ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size.
28790b57cec5SDimitry Andric if (!SrcIntPtrTy || DstIntPtrTy != SrcIntPtrTy)
28800b57cec5SDimitry Andric return 0;
28810b57cec5SDimitry Andric unsigned PtrSize = SrcIntPtrTy->getScalarSizeInBits();
28820b57cec5SDimitry Andric if (MidSize >= PtrSize)
28830b57cec5SDimitry Andric return Instruction::BitCast;
28840b57cec5SDimitry Andric return 0;
28850b57cec5SDimitry Andric }
28860b57cec5SDimitry Andric case 8: {
288781ad6265SDimitry Andric // ext, trunc -> bitcast, if the SrcTy and DstTy are the same
28880b57cec5SDimitry Andric // ext, trunc -> ext, if sizeof(SrcTy) < sizeof(DstTy)
28890b57cec5SDimitry Andric // ext, trunc -> trunc, if sizeof(SrcTy) > sizeof(DstTy)
28900b57cec5SDimitry Andric unsigned SrcSize = SrcTy->getScalarSizeInBits();
28910b57cec5SDimitry Andric unsigned DstSize = DstTy->getScalarSizeInBits();
289281ad6265SDimitry Andric if (SrcTy == DstTy)
28930b57cec5SDimitry Andric return Instruction::BitCast;
289481ad6265SDimitry Andric if (SrcSize < DstSize)
28950b57cec5SDimitry Andric return firstOp;
289681ad6265SDimitry Andric if (SrcSize > DstSize)
28970b57cec5SDimitry Andric return secondOp;
289881ad6265SDimitry Andric return 0;
28990b57cec5SDimitry Andric }
29000b57cec5SDimitry Andric case 9:
29010b57cec5SDimitry Andric // zext, sext -> zext, because sext can't sign extend after zext
29020b57cec5SDimitry Andric return Instruction::ZExt;
29030b57cec5SDimitry Andric case 11: {
29040b57cec5SDimitry Andric // inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize
29050b57cec5SDimitry Andric if (!MidIntPtrTy)
29060b57cec5SDimitry Andric return 0;
29070b57cec5SDimitry Andric unsigned PtrSize = MidIntPtrTy->getScalarSizeInBits();
29080b57cec5SDimitry Andric unsigned SrcSize = SrcTy->getScalarSizeInBits();
29090b57cec5SDimitry Andric unsigned DstSize = DstTy->getScalarSizeInBits();
29100b57cec5SDimitry Andric if (SrcSize <= PtrSize && SrcSize == DstSize)
29110b57cec5SDimitry Andric return Instruction::BitCast;
29120b57cec5SDimitry Andric return 0;
29130b57cec5SDimitry Andric }
29140b57cec5SDimitry Andric case 12:
29150b57cec5SDimitry Andric // addrspacecast, addrspacecast -> bitcast, if SrcAS == DstAS
29160b57cec5SDimitry Andric // addrspacecast, addrspacecast -> addrspacecast, if SrcAS != DstAS
29170b57cec5SDimitry Andric if (SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace())
29180b57cec5SDimitry Andric return Instruction::AddrSpaceCast;
29190b57cec5SDimitry Andric return Instruction::BitCast;
29200b57cec5SDimitry Andric case 13:
29210b57cec5SDimitry Andric // FIXME: this state can be merged with (1), but the following assert
29220b57cec5SDimitry Andric // is useful to check the correcteness of the sequence due to semantic
29230b57cec5SDimitry Andric // change of bitcast.
29240b57cec5SDimitry Andric assert(
29250b57cec5SDimitry Andric SrcTy->isPtrOrPtrVectorTy() &&
29260b57cec5SDimitry Andric MidTy->isPtrOrPtrVectorTy() &&
29270b57cec5SDimitry Andric DstTy->isPtrOrPtrVectorTy() &&
29280b57cec5SDimitry Andric SrcTy->getPointerAddressSpace() != MidTy->getPointerAddressSpace() &&
29290b57cec5SDimitry Andric MidTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() &&
29300b57cec5SDimitry Andric "Illegal addrspacecast, bitcast sequence!");
29310b57cec5SDimitry Andric // Allowed, use first cast's opcode
29320b57cec5SDimitry Andric return firstOp;
293306c3fb27SDimitry Andric case 14:
293406c3fb27SDimitry Andric // bitcast, addrspacecast -> addrspacecast
29350b57cec5SDimitry Andric return Instruction::AddrSpaceCast;
29360b57cec5SDimitry Andric case 15:
29370b57cec5SDimitry Andric // FIXME: this state can be merged with (1), but the following assert
29380b57cec5SDimitry Andric // is useful to check the correcteness of the sequence due to semantic
29390b57cec5SDimitry Andric // change of bitcast.
29400b57cec5SDimitry Andric assert(
29410b57cec5SDimitry Andric SrcTy->isIntOrIntVectorTy() &&
29420b57cec5SDimitry Andric MidTy->isPtrOrPtrVectorTy() &&
29430b57cec5SDimitry Andric DstTy->isPtrOrPtrVectorTy() &&
29440b57cec5SDimitry Andric MidTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() &&
29450b57cec5SDimitry Andric "Illegal inttoptr, bitcast sequence!");
29460b57cec5SDimitry Andric // Allowed, use first cast's opcode
29470b57cec5SDimitry Andric return firstOp;
29480b57cec5SDimitry Andric case 16:
29490b57cec5SDimitry Andric // FIXME: this state can be merged with (2), but the following assert
29500b57cec5SDimitry Andric // is useful to check the correcteness of the sequence due to semantic
29510b57cec5SDimitry Andric // change of bitcast.
29520b57cec5SDimitry Andric assert(
29530b57cec5SDimitry Andric SrcTy->isPtrOrPtrVectorTy() &&
29540b57cec5SDimitry Andric MidTy->isPtrOrPtrVectorTy() &&
29550b57cec5SDimitry Andric DstTy->isIntOrIntVectorTy() &&
29560b57cec5SDimitry Andric SrcTy->getPointerAddressSpace() == MidTy->getPointerAddressSpace() &&
29570b57cec5SDimitry Andric "Illegal bitcast, ptrtoint sequence!");
29580b57cec5SDimitry Andric // Allowed, use second cast's opcode
29590b57cec5SDimitry Andric return secondOp;
29600b57cec5SDimitry Andric case 17:
29610b57cec5SDimitry Andric // (sitofp (zext x)) -> (uitofp x)
29620b57cec5SDimitry Andric return Instruction::UIToFP;
29630b57cec5SDimitry Andric case 99:
29640b57cec5SDimitry Andric // Cast combination can't happen (error in input). This is for all cases
29650b57cec5SDimitry Andric // where the MidTy is not the same for the two cast instructions.
29660b57cec5SDimitry Andric llvm_unreachable("Invalid Cast Combination");
29670b57cec5SDimitry Andric default:
29680b57cec5SDimitry Andric llvm_unreachable("Error in CastResults table!!!");
29690b57cec5SDimitry Andric }
29700b57cec5SDimitry Andric }
29710b57cec5SDimitry Andric
Create(Instruction::CastOps op,Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)29720b57cec5SDimitry Andric CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty,
2973*0fca6ea1SDimitry Andric const Twine &Name, InsertPosition InsertBefore) {
29740b57cec5SDimitry Andric assert(castIsValid(op, S, Ty) && "Invalid cast!");
29750b57cec5SDimitry Andric // Construct and return the appropriate CastInst subclass
29760b57cec5SDimitry Andric switch (op) {
29770b57cec5SDimitry Andric case Trunc: return new TruncInst (S, Ty, Name, InsertBefore);
29780b57cec5SDimitry Andric case ZExt: return new ZExtInst (S, Ty, Name, InsertBefore);
29790b57cec5SDimitry Andric case SExt: return new SExtInst (S, Ty, Name, InsertBefore);
29800b57cec5SDimitry Andric case FPTrunc: return new FPTruncInst (S, Ty, Name, InsertBefore);
29810b57cec5SDimitry Andric case FPExt: return new FPExtInst (S, Ty, Name, InsertBefore);
29820b57cec5SDimitry Andric case UIToFP: return new UIToFPInst (S, Ty, Name, InsertBefore);
29830b57cec5SDimitry Andric case SIToFP: return new SIToFPInst (S, Ty, Name, InsertBefore);
29840b57cec5SDimitry Andric case FPToUI: return new FPToUIInst (S, Ty, Name, InsertBefore);
29850b57cec5SDimitry Andric case FPToSI: return new FPToSIInst (S, Ty, Name, InsertBefore);
29860b57cec5SDimitry Andric case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore);
29870b57cec5SDimitry Andric case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore);
2988*0fca6ea1SDimitry Andric case BitCast:
2989*0fca6ea1SDimitry Andric return new BitCastInst(S, Ty, Name, InsertBefore);
2990*0fca6ea1SDimitry Andric case AddrSpaceCast:
2991*0fca6ea1SDimitry Andric return new AddrSpaceCastInst(S, Ty, Name, InsertBefore);
2992*0fca6ea1SDimitry Andric default:
2993*0fca6ea1SDimitry Andric llvm_unreachable("Invalid opcode provided");
29940b57cec5SDimitry Andric }
29950b57cec5SDimitry Andric }
29960b57cec5SDimitry Andric
CreateZExtOrBitCast(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)2997*0fca6ea1SDimitry Andric CastInst *CastInst::CreateZExtOrBitCast(Value *S, Type *Ty, const Twine &Name,
2998*0fca6ea1SDimitry Andric InsertPosition InsertBefore) {
29990b57cec5SDimitry Andric if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
30000b57cec5SDimitry Andric return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
30010b57cec5SDimitry Andric return Create(Instruction::ZExt, S, Ty, Name, InsertBefore);
30020b57cec5SDimitry Andric }
30030b57cec5SDimitry Andric
CreateSExtOrBitCast(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3004*0fca6ea1SDimitry Andric CastInst *CastInst::CreateSExtOrBitCast(Value *S, Type *Ty, const Twine &Name,
3005*0fca6ea1SDimitry Andric InsertPosition InsertBefore) {
30060b57cec5SDimitry Andric if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
30070b57cec5SDimitry Andric return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
30080b57cec5SDimitry Andric return Create(Instruction::SExt, S, Ty, Name, InsertBefore);
30090b57cec5SDimitry Andric }
30100b57cec5SDimitry Andric
CreateTruncOrBitCast(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3011*0fca6ea1SDimitry Andric CastInst *CastInst::CreateTruncOrBitCast(Value *S, Type *Ty, const Twine &Name,
3012*0fca6ea1SDimitry Andric InsertPosition InsertBefore) {
30130b57cec5SDimitry Andric if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
30140b57cec5SDimitry Andric return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
30150b57cec5SDimitry Andric return Create(Instruction::Trunc, S, Ty, Name, InsertBefore);
30160b57cec5SDimitry Andric }
30170b57cec5SDimitry Andric
30180b57cec5SDimitry Andric /// Create a BitCast or a PtrToInt cast instruction
CreatePointerCast(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3019*0fca6ea1SDimitry Andric CastInst *CastInst::CreatePointerCast(Value *S, Type *Ty, const Twine &Name,
3020*0fca6ea1SDimitry Andric InsertPosition InsertBefore) {
30210b57cec5SDimitry Andric assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast");
30220b57cec5SDimitry Andric assert((Ty->isIntOrIntVectorTy() || Ty->isPtrOrPtrVectorTy()) &&
30230b57cec5SDimitry Andric "Invalid cast");
30240b57cec5SDimitry Andric assert(Ty->isVectorTy() == S->getType()->isVectorTy() && "Invalid cast");
30250b57cec5SDimitry Andric assert((!Ty->isVectorTy() ||
3026e8d8bef9SDimitry Andric cast<VectorType>(Ty)->getElementCount() ==
3027e8d8bef9SDimitry Andric cast<VectorType>(S->getType())->getElementCount()) &&
30280b57cec5SDimitry Andric "Invalid cast");
30290b57cec5SDimitry Andric
30300b57cec5SDimitry Andric if (Ty->isIntOrIntVectorTy())
30310b57cec5SDimitry Andric return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore);
30320b57cec5SDimitry Andric
30330b57cec5SDimitry Andric return CreatePointerBitCastOrAddrSpaceCast(S, Ty, Name, InsertBefore);
30340b57cec5SDimitry Andric }
30350b57cec5SDimitry Andric
CreatePointerBitCastOrAddrSpaceCast(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)30360b57cec5SDimitry Andric CastInst *CastInst::CreatePointerBitCastOrAddrSpaceCast(
3037*0fca6ea1SDimitry Andric Value *S, Type *Ty, const Twine &Name, InsertPosition InsertBefore) {
30380b57cec5SDimitry Andric assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast");
30390b57cec5SDimitry Andric assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast");
30400b57cec5SDimitry Andric
30410b57cec5SDimitry Andric if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace())
30420b57cec5SDimitry Andric return Create(Instruction::AddrSpaceCast, S, Ty, Name, InsertBefore);
30430b57cec5SDimitry Andric
30440b57cec5SDimitry Andric return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
30450b57cec5SDimitry Andric }
30460b57cec5SDimitry Andric
CreateBitOrPointerCast(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)30470b57cec5SDimitry Andric CastInst *CastInst::CreateBitOrPointerCast(Value *S, Type *Ty,
30480b57cec5SDimitry Andric const Twine &Name,
3049*0fca6ea1SDimitry Andric InsertPosition InsertBefore) {
30500b57cec5SDimitry Andric if (S->getType()->isPointerTy() && Ty->isIntegerTy())
30510b57cec5SDimitry Andric return Create(Instruction::PtrToInt, S, Ty, Name, InsertBefore);
30520b57cec5SDimitry Andric if (S->getType()->isIntegerTy() && Ty->isPointerTy())
30530b57cec5SDimitry Andric return Create(Instruction::IntToPtr, S, Ty, Name, InsertBefore);
30540b57cec5SDimitry Andric
30550b57cec5SDimitry Andric return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
30560b57cec5SDimitry Andric }
30570b57cec5SDimitry Andric
CreateIntegerCast(Value * C,Type * Ty,bool isSigned,const Twine & Name,InsertPosition InsertBefore)3058*0fca6ea1SDimitry Andric CastInst *CastInst::CreateIntegerCast(Value *C, Type *Ty, bool isSigned,
3059*0fca6ea1SDimitry Andric const Twine &Name,
3060*0fca6ea1SDimitry Andric InsertPosition InsertBefore) {
30610b57cec5SDimitry Andric assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() &&
30620b57cec5SDimitry Andric "Invalid integer cast");
30630b57cec5SDimitry Andric unsigned SrcBits = C->getType()->getScalarSizeInBits();
30640b57cec5SDimitry Andric unsigned DstBits = Ty->getScalarSizeInBits();
30650b57cec5SDimitry Andric Instruction::CastOps opcode =
30660b57cec5SDimitry Andric (SrcBits == DstBits ? Instruction::BitCast :
30670b57cec5SDimitry Andric (SrcBits > DstBits ? Instruction::Trunc :
30680b57cec5SDimitry Andric (isSigned ? Instruction::SExt : Instruction::ZExt)));
30690b57cec5SDimitry Andric return Create(opcode, C, Ty, Name, InsertBefore);
30700b57cec5SDimitry Andric }
30710b57cec5SDimitry Andric
CreateFPCast(Value * C,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3072*0fca6ea1SDimitry Andric CastInst *CastInst::CreateFPCast(Value *C, Type *Ty, const Twine &Name,
3073*0fca6ea1SDimitry Andric InsertPosition InsertBefore) {
30740b57cec5SDimitry Andric assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
30750b57cec5SDimitry Andric "Invalid cast");
30760b57cec5SDimitry Andric unsigned SrcBits = C->getType()->getScalarSizeInBits();
30770b57cec5SDimitry Andric unsigned DstBits = Ty->getScalarSizeInBits();
3078*0fca6ea1SDimitry Andric assert((C->getType() == Ty || SrcBits != DstBits) && "Invalid cast");
30790b57cec5SDimitry Andric Instruction::CastOps opcode =
30800b57cec5SDimitry Andric (SrcBits == DstBits ? Instruction::BitCast :
30810b57cec5SDimitry Andric (SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt));
30820b57cec5SDimitry Andric return Create(opcode, C, Ty, Name, InsertBefore);
30830b57cec5SDimitry Andric }
30840b57cec5SDimitry Andric
isBitCastable(Type * SrcTy,Type * DestTy)30850b57cec5SDimitry Andric bool CastInst::isBitCastable(Type *SrcTy, Type *DestTy) {
30860b57cec5SDimitry Andric if (!SrcTy->isFirstClassType() || !DestTy->isFirstClassType())
30870b57cec5SDimitry Andric return false;
30880b57cec5SDimitry Andric
30890b57cec5SDimitry Andric if (SrcTy == DestTy)
30900b57cec5SDimitry Andric return true;
30910b57cec5SDimitry Andric
30920b57cec5SDimitry Andric if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) {
30930b57cec5SDimitry Andric if (VectorType *DestVecTy = dyn_cast<VectorType>(DestTy)) {
30948bcb0991SDimitry Andric if (SrcVecTy->getElementCount() == DestVecTy->getElementCount()) {
30950b57cec5SDimitry Andric // An element by element cast. Valid if casting the elements is valid.
30960b57cec5SDimitry Andric SrcTy = SrcVecTy->getElementType();
30970b57cec5SDimitry Andric DestTy = DestVecTy->getElementType();
30980b57cec5SDimitry Andric }
30990b57cec5SDimitry Andric }
31000b57cec5SDimitry Andric }
31010b57cec5SDimitry Andric
31020b57cec5SDimitry Andric if (PointerType *DestPtrTy = dyn_cast<PointerType>(DestTy)) {
31030b57cec5SDimitry Andric if (PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy)) {
31040b57cec5SDimitry Andric return SrcPtrTy->getAddressSpace() == DestPtrTy->getAddressSpace();
31050b57cec5SDimitry Andric }
31060b57cec5SDimitry Andric }
31070b57cec5SDimitry Andric
31088bcb0991SDimitry Andric TypeSize SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr
31098bcb0991SDimitry Andric TypeSize DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr
31100b57cec5SDimitry Andric
31110b57cec5SDimitry Andric // Could still have vectors of pointers if the number of elements doesn't
31120b57cec5SDimitry Andric // match
3113bdd1243dSDimitry Andric if (SrcBits.getKnownMinValue() == 0 || DestBits.getKnownMinValue() == 0)
31140b57cec5SDimitry Andric return false;
31150b57cec5SDimitry Andric
31160b57cec5SDimitry Andric if (SrcBits != DestBits)
31170b57cec5SDimitry Andric return false;
31180b57cec5SDimitry Andric
31190b57cec5SDimitry Andric if (DestTy->isX86_MMXTy() || SrcTy->isX86_MMXTy())
31200b57cec5SDimitry Andric return false;
31210b57cec5SDimitry Andric
31220b57cec5SDimitry Andric return true;
31230b57cec5SDimitry Andric }
31240b57cec5SDimitry Andric
isBitOrNoopPointerCastable(Type * SrcTy,Type * DestTy,const DataLayout & DL)31250b57cec5SDimitry Andric bool CastInst::isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy,
31260b57cec5SDimitry Andric const DataLayout &DL) {
31270b57cec5SDimitry Andric // ptrtoint and inttoptr are not allowed on non-integral pointers
31280b57cec5SDimitry Andric if (auto *PtrTy = dyn_cast<PointerType>(SrcTy))
31290b57cec5SDimitry Andric if (auto *IntTy = dyn_cast<IntegerType>(DestTy))
31300b57cec5SDimitry Andric return (IntTy->getBitWidth() == DL.getPointerTypeSizeInBits(PtrTy) &&
31310b57cec5SDimitry Andric !DL.isNonIntegralPointerType(PtrTy));
31320b57cec5SDimitry Andric if (auto *PtrTy = dyn_cast<PointerType>(DestTy))
31330b57cec5SDimitry Andric if (auto *IntTy = dyn_cast<IntegerType>(SrcTy))
31340b57cec5SDimitry Andric return (IntTy->getBitWidth() == DL.getPointerTypeSizeInBits(PtrTy) &&
31350b57cec5SDimitry Andric !DL.isNonIntegralPointerType(PtrTy));
31360b57cec5SDimitry Andric
31370b57cec5SDimitry Andric return isBitCastable(SrcTy, DestTy);
31380b57cec5SDimitry Andric }
31390b57cec5SDimitry Andric
31400b57cec5SDimitry Andric // Provide a way to get a "cast" where the cast opcode is inferred from the
31410b57cec5SDimitry Andric // types and size of the operand. This, basically, is a parallel of the
31420b57cec5SDimitry Andric // logic in the castIsValid function below. This axiom should hold:
31430b57cec5SDimitry Andric // castIsValid( getCastOpcode(Val, Ty), Val, Ty)
31440b57cec5SDimitry Andric // should not assert in castIsValid. In other words, this produces a "correct"
31450b57cec5SDimitry Andric // casting opcode for the arguments passed to it.
31460b57cec5SDimitry Andric Instruction::CastOps
getCastOpcode(const Value * Src,bool SrcIsSigned,Type * DestTy,bool DestIsSigned)31470b57cec5SDimitry Andric CastInst::getCastOpcode(
31480b57cec5SDimitry Andric const Value *Src, bool SrcIsSigned, Type *DestTy, bool DestIsSigned) {
31490b57cec5SDimitry Andric Type *SrcTy = Src->getType();
31500b57cec5SDimitry Andric
31510b57cec5SDimitry Andric assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() &&
31520b57cec5SDimitry Andric "Only first class types are castable!");
31530b57cec5SDimitry Andric
31540b57cec5SDimitry Andric if (SrcTy == DestTy)
31550b57cec5SDimitry Andric return BitCast;
31560b57cec5SDimitry Andric
31570b57cec5SDimitry Andric // FIXME: Check address space sizes here
31580b57cec5SDimitry Andric if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy))
31590b57cec5SDimitry Andric if (VectorType *DestVecTy = dyn_cast<VectorType>(DestTy))
3160e8d8bef9SDimitry Andric if (SrcVecTy->getElementCount() == DestVecTy->getElementCount()) {
31610b57cec5SDimitry Andric // An element by element cast. Find the appropriate opcode based on the
31620b57cec5SDimitry Andric // element types.
31630b57cec5SDimitry Andric SrcTy = SrcVecTy->getElementType();
31640b57cec5SDimitry Andric DestTy = DestVecTy->getElementType();
31650b57cec5SDimitry Andric }
31660b57cec5SDimitry Andric
31670b57cec5SDimitry Andric // Get the bit sizes, we'll need these
31680b57cec5SDimitry Andric unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr
31690b57cec5SDimitry Andric unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr
31700b57cec5SDimitry Andric
31710b57cec5SDimitry Andric // Run through the possibilities ...
31720b57cec5SDimitry Andric if (DestTy->isIntegerTy()) { // Casting to integral
31730b57cec5SDimitry Andric if (SrcTy->isIntegerTy()) { // Casting from integral
31740b57cec5SDimitry Andric if (DestBits < SrcBits)
31750b57cec5SDimitry Andric return Trunc; // int -> smaller int
31760b57cec5SDimitry Andric else if (DestBits > SrcBits) { // its an extension
31770b57cec5SDimitry Andric if (SrcIsSigned)
31780b57cec5SDimitry Andric return SExt; // signed -> SEXT
31790b57cec5SDimitry Andric else
31800b57cec5SDimitry Andric return ZExt; // unsigned -> ZEXT
31810b57cec5SDimitry Andric } else {
31820b57cec5SDimitry Andric return BitCast; // Same size, No-op cast
31830b57cec5SDimitry Andric }
31840b57cec5SDimitry Andric } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
31850b57cec5SDimitry Andric if (DestIsSigned)
31860b57cec5SDimitry Andric return FPToSI; // FP -> sint
31870b57cec5SDimitry Andric else
31880b57cec5SDimitry Andric return FPToUI; // FP -> uint
31890b57cec5SDimitry Andric } else if (SrcTy->isVectorTy()) {
31900b57cec5SDimitry Andric assert(DestBits == SrcBits &&
31910b57cec5SDimitry Andric "Casting vector to integer of different width");
31920b57cec5SDimitry Andric return BitCast; // Same size, no-op cast
31930b57cec5SDimitry Andric } else {
31940b57cec5SDimitry Andric assert(SrcTy->isPointerTy() &&
31950b57cec5SDimitry Andric "Casting from a value that is not first-class type");
31960b57cec5SDimitry Andric return PtrToInt; // ptr -> int
31970b57cec5SDimitry Andric }
31980b57cec5SDimitry Andric } else if (DestTy->isFloatingPointTy()) { // Casting to floating pt
31990b57cec5SDimitry Andric if (SrcTy->isIntegerTy()) { // Casting from integral
32000b57cec5SDimitry Andric if (SrcIsSigned)
32010b57cec5SDimitry Andric return SIToFP; // sint -> FP
32020b57cec5SDimitry Andric else
32030b57cec5SDimitry Andric return UIToFP; // uint -> FP
32040b57cec5SDimitry Andric } else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
32050b57cec5SDimitry Andric if (DestBits < SrcBits) {
32060b57cec5SDimitry Andric return FPTrunc; // FP -> smaller FP
32070b57cec5SDimitry Andric } else if (DestBits > SrcBits) {
32080b57cec5SDimitry Andric return FPExt; // FP -> larger FP
32090b57cec5SDimitry Andric } else {
32100b57cec5SDimitry Andric return BitCast; // same size, no-op cast
32110b57cec5SDimitry Andric }
32120b57cec5SDimitry Andric } else if (SrcTy->isVectorTy()) {
32130b57cec5SDimitry Andric assert(DestBits == SrcBits &&
32140b57cec5SDimitry Andric "Casting vector to floating point of different width");
32150b57cec5SDimitry Andric return BitCast; // same size, no-op cast
32160b57cec5SDimitry Andric }
32170b57cec5SDimitry Andric llvm_unreachable("Casting pointer or non-first class to float");
32180b57cec5SDimitry Andric } else if (DestTy->isVectorTy()) {
32190b57cec5SDimitry Andric assert(DestBits == SrcBits &&
32200b57cec5SDimitry Andric "Illegal cast to vector (wrong type or size)");
32210b57cec5SDimitry Andric return BitCast;
32220b57cec5SDimitry Andric } else if (DestTy->isPointerTy()) {
32230b57cec5SDimitry Andric if (SrcTy->isPointerTy()) {
32240b57cec5SDimitry Andric if (DestTy->getPointerAddressSpace() != SrcTy->getPointerAddressSpace())
32250b57cec5SDimitry Andric return AddrSpaceCast;
32260b57cec5SDimitry Andric return BitCast; // ptr -> ptr
32270b57cec5SDimitry Andric } else if (SrcTy->isIntegerTy()) {
32280b57cec5SDimitry Andric return IntToPtr; // int -> ptr
32290b57cec5SDimitry Andric }
32300b57cec5SDimitry Andric llvm_unreachable("Casting pointer to other than pointer or int");
32310b57cec5SDimitry Andric } else if (DestTy->isX86_MMXTy()) {
32320b57cec5SDimitry Andric if (SrcTy->isVectorTy()) {
32330b57cec5SDimitry Andric assert(DestBits == SrcBits && "Casting vector of wrong width to X86_MMX");
32340b57cec5SDimitry Andric return BitCast; // 64-bit vector to MMX
32350b57cec5SDimitry Andric }
32360b57cec5SDimitry Andric llvm_unreachable("Illegal cast to X86_MMX");
32370b57cec5SDimitry Andric }
32380b57cec5SDimitry Andric llvm_unreachable("Casting to type that is not first-class");
32390b57cec5SDimitry Andric }
32400b57cec5SDimitry Andric
32410b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
32420b57cec5SDimitry Andric // CastInst SubClass Constructors
32430b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
32440b57cec5SDimitry Andric
32450b57cec5SDimitry Andric /// Check that the construction parameters for a CastInst are correct. This
32460b57cec5SDimitry Andric /// could be broken out into the separate constructors but it is useful to have
32470b57cec5SDimitry Andric /// it in one place and to eliminate the redundant code for getting the sizes
32480b57cec5SDimitry Andric /// of the types involved.
32490b57cec5SDimitry Andric bool
castIsValid(Instruction::CastOps op,Type * SrcTy,Type * DstTy)3250e8d8bef9SDimitry Andric CastInst::castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy) {
32510b57cec5SDimitry Andric if (!SrcTy->isFirstClassType() || !DstTy->isFirstClassType() ||
32520b57cec5SDimitry Andric SrcTy->isAggregateType() || DstTy->isAggregateType())
32530b57cec5SDimitry Andric return false;
32540b57cec5SDimitry Andric
32555ffd83dbSDimitry Andric // Get the size of the types in bits, and whether we are dealing
32565ffd83dbSDimitry Andric // with vector types, we'll need this later.
32575ffd83dbSDimitry Andric bool SrcIsVec = isa<VectorType>(SrcTy);
32585ffd83dbSDimitry Andric bool DstIsVec = isa<VectorType>(DstTy);
32595ffd83dbSDimitry Andric unsigned SrcScalarBitSize = SrcTy->getScalarSizeInBits();
32605ffd83dbSDimitry Andric unsigned DstScalarBitSize = DstTy->getScalarSizeInBits();
32610b57cec5SDimitry Andric
32620b57cec5SDimitry Andric // If these are vector types, get the lengths of the vectors (using zero for
32630b57cec5SDimitry Andric // scalar types means that checking that vector lengths match also checks that
32640b57cec5SDimitry Andric // scalars are not being converted to vectors or vectors to scalars).
32655ffd83dbSDimitry Andric ElementCount SrcEC = SrcIsVec ? cast<VectorType>(SrcTy)->getElementCount()
3266e8d8bef9SDimitry Andric : ElementCount::getFixed(0);
32675ffd83dbSDimitry Andric ElementCount DstEC = DstIsVec ? cast<VectorType>(DstTy)->getElementCount()
3268e8d8bef9SDimitry Andric : ElementCount::getFixed(0);
32690b57cec5SDimitry Andric
32700b57cec5SDimitry Andric // Switch on the opcode provided
32710b57cec5SDimitry Andric switch (op) {
32720b57cec5SDimitry Andric default: return false; // This is an input error
32730b57cec5SDimitry Andric case Instruction::Trunc:
32740b57cec5SDimitry Andric return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() &&
32755ffd83dbSDimitry Andric SrcEC == DstEC && SrcScalarBitSize > DstScalarBitSize;
32760b57cec5SDimitry Andric case Instruction::ZExt:
32770b57cec5SDimitry Andric return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() &&
32785ffd83dbSDimitry Andric SrcEC == DstEC && SrcScalarBitSize < DstScalarBitSize;
32790b57cec5SDimitry Andric case Instruction::SExt:
32800b57cec5SDimitry Andric return SrcTy->isIntOrIntVectorTy() && DstTy->isIntOrIntVectorTy() &&
32815ffd83dbSDimitry Andric SrcEC == DstEC && SrcScalarBitSize < DstScalarBitSize;
32820b57cec5SDimitry Andric case Instruction::FPTrunc:
32830b57cec5SDimitry Andric return SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy() &&
32845ffd83dbSDimitry Andric SrcEC == DstEC && SrcScalarBitSize > DstScalarBitSize;
32850b57cec5SDimitry Andric case Instruction::FPExt:
32860b57cec5SDimitry Andric return SrcTy->isFPOrFPVectorTy() && DstTy->isFPOrFPVectorTy() &&
32875ffd83dbSDimitry Andric SrcEC == DstEC && SrcScalarBitSize < DstScalarBitSize;
32880b57cec5SDimitry Andric case Instruction::UIToFP:
32890b57cec5SDimitry Andric case Instruction::SIToFP:
32900b57cec5SDimitry Andric return SrcTy->isIntOrIntVectorTy() && DstTy->isFPOrFPVectorTy() &&
32915ffd83dbSDimitry Andric SrcEC == DstEC;
32920b57cec5SDimitry Andric case Instruction::FPToUI:
32930b57cec5SDimitry Andric case Instruction::FPToSI:
32940b57cec5SDimitry Andric return SrcTy->isFPOrFPVectorTy() && DstTy->isIntOrIntVectorTy() &&
32955ffd83dbSDimitry Andric SrcEC == DstEC;
32960b57cec5SDimitry Andric case Instruction::PtrToInt:
32975ffd83dbSDimitry Andric if (SrcEC != DstEC)
32980b57cec5SDimitry Andric return false;
32990b57cec5SDimitry Andric return SrcTy->isPtrOrPtrVectorTy() && DstTy->isIntOrIntVectorTy();
33000b57cec5SDimitry Andric case Instruction::IntToPtr:
33015ffd83dbSDimitry Andric if (SrcEC != DstEC)
33020b57cec5SDimitry Andric return false;
33030b57cec5SDimitry Andric return SrcTy->isIntOrIntVectorTy() && DstTy->isPtrOrPtrVectorTy();
33040b57cec5SDimitry Andric case Instruction::BitCast: {
33050b57cec5SDimitry Andric PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy->getScalarType());
33060b57cec5SDimitry Andric PointerType *DstPtrTy = dyn_cast<PointerType>(DstTy->getScalarType());
33070b57cec5SDimitry Andric
33080b57cec5SDimitry Andric // BitCast implies a no-op cast of type only. No bits change.
33090b57cec5SDimitry Andric // However, you can't cast pointers to anything but pointers.
33100b57cec5SDimitry Andric if (!SrcPtrTy != !DstPtrTy)
33110b57cec5SDimitry Andric return false;
33120b57cec5SDimitry Andric
33130b57cec5SDimitry Andric // For non-pointer cases, the cast is okay if the source and destination bit
33140b57cec5SDimitry Andric // widths are identical.
33150b57cec5SDimitry Andric if (!SrcPtrTy)
33160b57cec5SDimitry Andric return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits();
33170b57cec5SDimitry Andric
33180b57cec5SDimitry Andric // If both are pointers then the address spaces must match.
33190b57cec5SDimitry Andric if (SrcPtrTy->getAddressSpace() != DstPtrTy->getAddressSpace())
33200b57cec5SDimitry Andric return false;
33210b57cec5SDimitry Andric
33220b57cec5SDimitry Andric // A vector of pointers must have the same number of elements.
33235ffd83dbSDimitry Andric if (SrcIsVec && DstIsVec)
33245ffd83dbSDimitry Andric return SrcEC == DstEC;
33255ffd83dbSDimitry Andric if (SrcIsVec)
3326e8d8bef9SDimitry Andric return SrcEC == ElementCount::getFixed(1);
33275ffd83dbSDimitry Andric if (DstIsVec)
3328e8d8bef9SDimitry Andric return DstEC == ElementCount::getFixed(1);
33290b57cec5SDimitry Andric
33300b57cec5SDimitry Andric return true;
33310b57cec5SDimitry Andric }
33320b57cec5SDimitry Andric case Instruction::AddrSpaceCast: {
33330b57cec5SDimitry Andric PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy->getScalarType());
33340b57cec5SDimitry Andric if (!SrcPtrTy)
33350b57cec5SDimitry Andric return false;
33360b57cec5SDimitry Andric
33370b57cec5SDimitry Andric PointerType *DstPtrTy = dyn_cast<PointerType>(DstTy->getScalarType());
33380b57cec5SDimitry Andric if (!DstPtrTy)
33390b57cec5SDimitry Andric return false;
33400b57cec5SDimitry Andric
33410b57cec5SDimitry Andric if (SrcPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace())
33420b57cec5SDimitry Andric return false;
33430b57cec5SDimitry Andric
33445ffd83dbSDimitry Andric return SrcEC == DstEC;
33450b57cec5SDimitry Andric }
33460b57cec5SDimitry Andric }
33470b57cec5SDimitry Andric }
33480b57cec5SDimitry Andric
TruncInst(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3349*0fca6ea1SDimitry Andric TruncInst::TruncInst(Value *S, Type *Ty, const Twine &Name,
3350*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
3351*0fca6ea1SDimitry Andric : CastInst(Ty, Trunc, S, Name, InsertBefore) {
33520b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal Trunc");
33530b57cec5SDimitry Andric }
33540b57cec5SDimitry Andric
ZExtInst(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3355*0fca6ea1SDimitry Andric ZExtInst::ZExtInst(Value *S, Type *Ty, const Twine &Name,
3356*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
3357*0fca6ea1SDimitry Andric : CastInst(Ty, ZExt, S, Name, InsertBefore) {
33580b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal ZExt");
33590b57cec5SDimitry Andric }
33600b57cec5SDimitry Andric
SExtInst(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3361*0fca6ea1SDimitry Andric SExtInst::SExtInst(Value *S, Type *Ty, const Twine &Name,
3362*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
3363*0fca6ea1SDimitry Andric : CastInst(Ty, SExt, S, Name, InsertBefore) {
33640b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal SExt");
33650b57cec5SDimitry Andric }
33660b57cec5SDimitry Andric
FPTruncInst(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3367*0fca6ea1SDimitry Andric FPTruncInst::FPTruncInst(Value *S, Type *Ty, const Twine &Name,
3368*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
3369*0fca6ea1SDimitry Andric : CastInst(Ty, FPTrunc, S, Name, InsertBefore) {
33700b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPTrunc");
33710b57cec5SDimitry Andric }
33720b57cec5SDimitry Andric
FPExtInst(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3373*0fca6ea1SDimitry Andric FPExtInst::FPExtInst(Value *S, Type *Ty, const Twine &Name,
3374*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
3375*0fca6ea1SDimitry Andric : CastInst(Ty, FPExt, S, Name, InsertBefore) {
33760b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPExt");
33770b57cec5SDimitry Andric }
33780b57cec5SDimitry Andric
UIToFPInst(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3379*0fca6ea1SDimitry Andric UIToFPInst::UIToFPInst(Value *S, Type *Ty, const Twine &Name,
3380*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
3381*0fca6ea1SDimitry Andric : CastInst(Ty, UIToFP, S, Name, InsertBefore) {
33820b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal UIToFP");
33830b57cec5SDimitry Andric }
33840b57cec5SDimitry Andric
SIToFPInst(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3385*0fca6ea1SDimitry Andric SIToFPInst::SIToFPInst(Value *S, Type *Ty, const Twine &Name,
3386*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
3387*0fca6ea1SDimitry Andric : CastInst(Ty, SIToFP, S, Name, InsertBefore) {
33880b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal SIToFP");
33890b57cec5SDimitry Andric }
33900b57cec5SDimitry Andric
FPToUIInst(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3391*0fca6ea1SDimitry Andric FPToUIInst::FPToUIInst(Value *S, Type *Ty, const Twine &Name,
3392*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
3393*0fca6ea1SDimitry Andric : CastInst(Ty, FPToUI, S, Name, InsertBefore) {
33940b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToUI");
33950b57cec5SDimitry Andric }
33960b57cec5SDimitry Andric
FPToSIInst(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3397*0fca6ea1SDimitry Andric FPToSIInst::FPToSIInst(Value *S, Type *Ty, const Twine &Name,
3398*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
3399*0fca6ea1SDimitry Andric : CastInst(Ty, FPToSI, S, Name, InsertBefore) {
34000b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal FPToSI");
34010b57cec5SDimitry Andric }
34020b57cec5SDimitry Andric
PtrToIntInst(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3403*0fca6ea1SDimitry Andric PtrToIntInst::PtrToIntInst(Value *S, Type *Ty, const Twine &Name,
3404*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
3405*0fca6ea1SDimitry Andric : CastInst(Ty, PtrToInt, S, Name, InsertBefore) {
34060b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal PtrToInt");
34070b57cec5SDimitry Andric }
34080b57cec5SDimitry Andric
IntToPtrInst(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3409*0fca6ea1SDimitry Andric IntToPtrInst::IntToPtrInst(Value *S, Type *Ty, const Twine &Name,
3410*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
3411*0fca6ea1SDimitry Andric : CastInst(Ty, IntToPtr, S, Name, InsertBefore) {
34120b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal IntToPtr");
34130b57cec5SDimitry Andric }
34140b57cec5SDimitry Andric
BitCastInst(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3415*0fca6ea1SDimitry Andric BitCastInst::BitCastInst(Value *S, Type *Ty, const Twine &Name,
3416*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
3417*0fca6ea1SDimitry Andric : CastInst(Ty, BitCast, S, Name, InsertBefore) {
34180b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal BitCast");
34190b57cec5SDimitry Andric }
34200b57cec5SDimitry Andric
AddrSpaceCastInst(Value * S,Type * Ty,const Twine & Name,InsertPosition InsertBefore)3421*0fca6ea1SDimitry Andric AddrSpaceCastInst::AddrSpaceCastInst(Value *S, Type *Ty, const Twine &Name,
3422*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
3423*0fca6ea1SDimitry Andric : CastInst(Ty, AddrSpaceCast, S, Name, InsertBefore) {
34240b57cec5SDimitry Andric assert(castIsValid(getOpcode(), S, Ty) && "Illegal AddrSpaceCast");
34250b57cec5SDimitry Andric }
34260b57cec5SDimitry Andric
34270b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
34280b57cec5SDimitry Andric // CmpInst Classes
34290b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
34300b57cec5SDimitry Andric
CmpInst(Type * ty,OtherOps op,Predicate predicate,Value * LHS,Value * RHS,const Twine & Name,InsertPosition InsertBefore,Instruction * FlagsSource)34310b57cec5SDimitry Andric CmpInst::CmpInst(Type *ty, OtherOps op, Predicate predicate, Value *LHS,
3432*0fca6ea1SDimitry Andric Value *RHS, const Twine &Name, InsertPosition InsertBefore,
34330b57cec5SDimitry Andric Instruction *FlagsSource)
3434*0fca6ea1SDimitry Andric : Instruction(ty, op, OperandTraits<CmpInst>::op_begin(this),
3435*0fca6ea1SDimitry Andric OperandTraits<CmpInst>::operands(this), InsertBefore) {
34360b57cec5SDimitry Andric Op<0>() = LHS;
34370b57cec5SDimitry Andric Op<1>() = RHS;
34380b57cec5SDimitry Andric setPredicate((Predicate)predicate);
34390b57cec5SDimitry Andric setName(Name);
34400b57cec5SDimitry Andric if (FlagsSource)
34410b57cec5SDimitry Andric copyIRFlags(FlagsSource);
34420b57cec5SDimitry Andric }
34430b57cec5SDimitry Andric
Create(OtherOps Op,Predicate predicate,Value * S1,Value * S2,const Twine & Name,InsertPosition InsertBefore)3444*0fca6ea1SDimitry Andric CmpInst *CmpInst::Create(OtherOps Op, Predicate predicate, Value *S1, Value *S2,
3445*0fca6ea1SDimitry Andric const Twine &Name, InsertPosition InsertBefore) {
34460b57cec5SDimitry Andric if (Op == Instruction::ICmp) {
3447*0fca6ea1SDimitry Andric if (InsertBefore.isValid())
34480b57cec5SDimitry Andric return new ICmpInst(InsertBefore, CmpInst::Predicate(predicate),
34490b57cec5SDimitry Andric S1, S2, Name);
34500b57cec5SDimitry Andric else
34510b57cec5SDimitry Andric return new ICmpInst(CmpInst::Predicate(predicate),
34520b57cec5SDimitry Andric S1, S2, Name);
34530b57cec5SDimitry Andric }
34540b57cec5SDimitry Andric
3455*0fca6ea1SDimitry Andric if (InsertBefore.isValid())
34560b57cec5SDimitry Andric return new FCmpInst(InsertBefore, CmpInst::Predicate(predicate),
34570b57cec5SDimitry Andric S1, S2, Name);
34580b57cec5SDimitry Andric else
34590b57cec5SDimitry Andric return new FCmpInst(CmpInst::Predicate(predicate),
34600b57cec5SDimitry Andric S1, S2, Name);
34610b57cec5SDimitry Andric }
34620b57cec5SDimitry Andric
CreateWithCopiedFlags(OtherOps Op,Predicate Pred,Value * S1,Value * S2,const Instruction * FlagsSource,const Twine & Name,InsertPosition InsertBefore)3463*0fca6ea1SDimitry Andric CmpInst *CmpInst::CreateWithCopiedFlags(OtherOps Op, Predicate Pred, Value *S1,
3464*0fca6ea1SDimitry Andric Value *S2,
3465*0fca6ea1SDimitry Andric const Instruction *FlagsSource,
3466*0fca6ea1SDimitry Andric const Twine &Name,
3467*0fca6ea1SDimitry Andric InsertPosition InsertBefore) {
3468*0fca6ea1SDimitry Andric CmpInst *Inst = Create(Op, Pred, S1, S2, Name, InsertBefore);
3469*0fca6ea1SDimitry Andric Inst->copyIRFlags(FlagsSource);
3470*0fca6ea1SDimitry Andric return Inst;
34710b57cec5SDimitry Andric }
34720b57cec5SDimitry Andric
swapOperands()34730b57cec5SDimitry Andric void CmpInst::swapOperands() {
34740b57cec5SDimitry Andric if (ICmpInst *IC = dyn_cast<ICmpInst>(this))
34750b57cec5SDimitry Andric IC->swapOperands();
34760b57cec5SDimitry Andric else
34770b57cec5SDimitry Andric cast<FCmpInst>(this)->swapOperands();
34780b57cec5SDimitry Andric }
34790b57cec5SDimitry Andric
isCommutative() const34800b57cec5SDimitry Andric bool CmpInst::isCommutative() const {
34810b57cec5SDimitry Andric if (const ICmpInst *IC = dyn_cast<ICmpInst>(this))
34820b57cec5SDimitry Andric return IC->isCommutative();
34830b57cec5SDimitry Andric return cast<FCmpInst>(this)->isCommutative();
34840b57cec5SDimitry Andric }
34850b57cec5SDimitry Andric
isEquality(Predicate P)3486e8d8bef9SDimitry Andric bool CmpInst::isEquality(Predicate P) {
3487e8d8bef9SDimitry Andric if (ICmpInst::isIntPredicate(P))
3488e8d8bef9SDimitry Andric return ICmpInst::isEquality(P);
3489e8d8bef9SDimitry Andric if (FCmpInst::isFPPredicate(P))
3490e8d8bef9SDimitry Andric return FCmpInst::isEquality(P);
3491e8d8bef9SDimitry Andric llvm_unreachable("Unsupported predicate kind");
34920b57cec5SDimitry Andric }
34930b57cec5SDimitry Andric
getInversePredicate(Predicate pred)34940b57cec5SDimitry Andric CmpInst::Predicate CmpInst::getInversePredicate(Predicate pred) {
34950b57cec5SDimitry Andric switch (pred) {
34960b57cec5SDimitry Andric default: llvm_unreachable("Unknown cmp predicate!");
34970b57cec5SDimitry Andric case ICMP_EQ: return ICMP_NE;
34980b57cec5SDimitry Andric case ICMP_NE: return ICMP_EQ;
34990b57cec5SDimitry Andric case ICMP_UGT: return ICMP_ULE;
35000b57cec5SDimitry Andric case ICMP_ULT: return ICMP_UGE;
35010b57cec5SDimitry Andric case ICMP_UGE: return ICMP_ULT;
35020b57cec5SDimitry Andric case ICMP_ULE: return ICMP_UGT;
35030b57cec5SDimitry Andric case ICMP_SGT: return ICMP_SLE;
35040b57cec5SDimitry Andric case ICMP_SLT: return ICMP_SGE;
35050b57cec5SDimitry Andric case ICMP_SGE: return ICMP_SLT;
35060b57cec5SDimitry Andric case ICMP_SLE: return ICMP_SGT;
35070b57cec5SDimitry Andric
35080b57cec5SDimitry Andric case FCMP_OEQ: return FCMP_UNE;
35090b57cec5SDimitry Andric case FCMP_ONE: return FCMP_UEQ;
35100b57cec5SDimitry Andric case FCMP_OGT: return FCMP_ULE;
35110b57cec5SDimitry Andric case FCMP_OLT: return FCMP_UGE;
35120b57cec5SDimitry Andric case FCMP_OGE: return FCMP_ULT;
35130b57cec5SDimitry Andric case FCMP_OLE: return FCMP_UGT;
35140b57cec5SDimitry Andric case FCMP_UEQ: return FCMP_ONE;
35150b57cec5SDimitry Andric case FCMP_UNE: return FCMP_OEQ;
35160b57cec5SDimitry Andric case FCMP_UGT: return FCMP_OLE;
35170b57cec5SDimitry Andric case FCMP_ULT: return FCMP_OGE;
35180b57cec5SDimitry Andric case FCMP_UGE: return FCMP_OLT;
35190b57cec5SDimitry Andric case FCMP_ULE: return FCMP_OGT;
35200b57cec5SDimitry Andric case FCMP_ORD: return FCMP_UNO;
35210b57cec5SDimitry Andric case FCMP_UNO: return FCMP_ORD;
35220b57cec5SDimitry Andric case FCMP_TRUE: return FCMP_FALSE;
35230b57cec5SDimitry Andric case FCMP_FALSE: return FCMP_TRUE;
35240b57cec5SDimitry Andric }
35250b57cec5SDimitry Andric }
35260b57cec5SDimitry Andric
getPredicateName(Predicate Pred)35270b57cec5SDimitry Andric StringRef CmpInst::getPredicateName(Predicate Pred) {
35280b57cec5SDimitry Andric switch (Pred) {
35290b57cec5SDimitry Andric default: return "unknown";
35300b57cec5SDimitry Andric case FCmpInst::FCMP_FALSE: return "false";
35310b57cec5SDimitry Andric case FCmpInst::FCMP_OEQ: return "oeq";
35320b57cec5SDimitry Andric case FCmpInst::FCMP_OGT: return "ogt";
35330b57cec5SDimitry Andric case FCmpInst::FCMP_OGE: return "oge";
35340b57cec5SDimitry Andric case FCmpInst::FCMP_OLT: return "olt";
35350b57cec5SDimitry Andric case FCmpInst::FCMP_OLE: return "ole";
35360b57cec5SDimitry Andric case FCmpInst::FCMP_ONE: return "one";
35370b57cec5SDimitry Andric case FCmpInst::FCMP_ORD: return "ord";
35380b57cec5SDimitry Andric case FCmpInst::FCMP_UNO: return "uno";
35390b57cec5SDimitry Andric case FCmpInst::FCMP_UEQ: return "ueq";
35400b57cec5SDimitry Andric case FCmpInst::FCMP_UGT: return "ugt";
35410b57cec5SDimitry Andric case FCmpInst::FCMP_UGE: return "uge";
35420b57cec5SDimitry Andric case FCmpInst::FCMP_ULT: return "ult";
35430b57cec5SDimitry Andric case FCmpInst::FCMP_ULE: return "ule";
35440b57cec5SDimitry Andric case FCmpInst::FCMP_UNE: return "une";
35450b57cec5SDimitry Andric case FCmpInst::FCMP_TRUE: return "true";
35460b57cec5SDimitry Andric case ICmpInst::ICMP_EQ: return "eq";
35470b57cec5SDimitry Andric case ICmpInst::ICMP_NE: return "ne";
35480b57cec5SDimitry Andric case ICmpInst::ICMP_SGT: return "sgt";
35490b57cec5SDimitry Andric case ICmpInst::ICMP_SGE: return "sge";
35500b57cec5SDimitry Andric case ICmpInst::ICMP_SLT: return "slt";
35510b57cec5SDimitry Andric case ICmpInst::ICMP_SLE: return "sle";
35520b57cec5SDimitry Andric case ICmpInst::ICMP_UGT: return "ugt";
35530b57cec5SDimitry Andric case ICmpInst::ICMP_UGE: return "uge";
35540b57cec5SDimitry Andric case ICmpInst::ICMP_ULT: return "ult";
35550b57cec5SDimitry Andric case ICmpInst::ICMP_ULE: return "ule";
35560b57cec5SDimitry Andric }
35570b57cec5SDimitry Andric }
35580b57cec5SDimitry Andric
operator <<(raw_ostream & OS,CmpInst::Predicate Pred)355906c3fb27SDimitry Andric raw_ostream &llvm::operator<<(raw_ostream &OS, CmpInst::Predicate Pred) {
356006c3fb27SDimitry Andric OS << CmpInst::getPredicateName(Pred);
356106c3fb27SDimitry Andric return OS;
356206c3fb27SDimitry Andric }
356306c3fb27SDimitry Andric
getSignedPredicate(Predicate pred)35640b57cec5SDimitry Andric ICmpInst::Predicate ICmpInst::getSignedPredicate(Predicate pred) {
35650b57cec5SDimitry Andric switch (pred) {
35660b57cec5SDimitry Andric default: llvm_unreachable("Unknown icmp predicate!");
35670b57cec5SDimitry Andric case ICMP_EQ: case ICMP_NE:
35680b57cec5SDimitry Andric case ICMP_SGT: case ICMP_SLT: case ICMP_SGE: case ICMP_SLE:
35690b57cec5SDimitry Andric return pred;
35700b57cec5SDimitry Andric case ICMP_UGT: return ICMP_SGT;
35710b57cec5SDimitry Andric case ICMP_ULT: return ICMP_SLT;
35720b57cec5SDimitry Andric case ICMP_UGE: return ICMP_SGE;
35730b57cec5SDimitry Andric case ICMP_ULE: return ICMP_SLE;
35740b57cec5SDimitry Andric }
35750b57cec5SDimitry Andric }
35760b57cec5SDimitry Andric
getUnsignedPredicate(Predicate pred)35770b57cec5SDimitry Andric ICmpInst::Predicate ICmpInst::getUnsignedPredicate(Predicate pred) {
35780b57cec5SDimitry Andric switch (pred) {
35790b57cec5SDimitry Andric default: llvm_unreachable("Unknown icmp predicate!");
35800b57cec5SDimitry Andric case ICMP_EQ: case ICMP_NE:
35810b57cec5SDimitry Andric case ICMP_UGT: case ICMP_ULT: case ICMP_UGE: case ICMP_ULE:
35820b57cec5SDimitry Andric return pred;
35830b57cec5SDimitry Andric case ICMP_SGT: return ICMP_UGT;
35840b57cec5SDimitry Andric case ICMP_SLT: return ICMP_ULT;
35850b57cec5SDimitry Andric case ICMP_SGE: return ICMP_UGE;
35860b57cec5SDimitry Andric case ICMP_SLE: return ICMP_ULE;
35870b57cec5SDimitry Andric }
35880b57cec5SDimitry Andric }
35890b57cec5SDimitry Andric
getSwappedPredicate(Predicate pred)35900b57cec5SDimitry Andric CmpInst::Predicate CmpInst::getSwappedPredicate(Predicate pred) {
35910b57cec5SDimitry Andric switch (pred) {
35920b57cec5SDimitry Andric default: llvm_unreachable("Unknown cmp predicate!");
35930b57cec5SDimitry Andric case ICMP_EQ: case ICMP_NE:
35940b57cec5SDimitry Andric return pred;
35950b57cec5SDimitry Andric case ICMP_SGT: return ICMP_SLT;
35960b57cec5SDimitry Andric case ICMP_SLT: return ICMP_SGT;
35970b57cec5SDimitry Andric case ICMP_SGE: return ICMP_SLE;
35980b57cec5SDimitry Andric case ICMP_SLE: return ICMP_SGE;
35990b57cec5SDimitry Andric case ICMP_UGT: return ICMP_ULT;
36000b57cec5SDimitry Andric case ICMP_ULT: return ICMP_UGT;
36010b57cec5SDimitry Andric case ICMP_UGE: return ICMP_ULE;
36020b57cec5SDimitry Andric case ICMP_ULE: return ICMP_UGE;
36030b57cec5SDimitry Andric
36040b57cec5SDimitry Andric case FCMP_FALSE: case FCMP_TRUE:
36050b57cec5SDimitry Andric case FCMP_OEQ: case FCMP_ONE:
36060b57cec5SDimitry Andric case FCMP_UEQ: case FCMP_UNE:
36070b57cec5SDimitry Andric case FCMP_ORD: case FCMP_UNO:
36080b57cec5SDimitry Andric return pred;
36090b57cec5SDimitry Andric case FCMP_OGT: return FCMP_OLT;
36100b57cec5SDimitry Andric case FCMP_OLT: return FCMP_OGT;
36110b57cec5SDimitry Andric case FCMP_OGE: return FCMP_OLE;
36120b57cec5SDimitry Andric case FCMP_OLE: return FCMP_OGE;
36130b57cec5SDimitry Andric case FCMP_UGT: return FCMP_ULT;
36140b57cec5SDimitry Andric case FCMP_ULT: return FCMP_UGT;
36150b57cec5SDimitry Andric case FCMP_UGE: return FCMP_ULE;
36160b57cec5SDimitry Andric case FCMP_ULE: return FCMP_UGE;
36170b57cec5SDimitry Andric }
36180b57cec5SDimitry Andric }
36190b57cec5SDimitry Andric
isNonStrictPredicate(Predicate pred)3620e8d8bef9SDimitry Andric bool CmpInst::isNonStrictPredicate(Predicate pred) {
36210b57cec5SDimitry Andric switch (pred) {
3622e8d8bef9SDimitry Andric case ICMP_SGE:
3623e8d8bef9SDimitry Andric case ICMP_SLE:
3624e8d8bef9SDimitry Andric case ICMP_UGE:
3625e8d8bef9SDimitry Andric case ICMP_ULE:
3626e8d8bef9SDimitry Andric case FCMP_OGE:
3627e8d8bef9SDimitry Andric case FCMP_OLE:
3628e8d8bef9SDimitry Andric case FCMP_UGE:
3629e8d8bef9SDimitry Andric case FCMP_ULE:
3630e8d8bef9SDimitry Andric return true;
3631e8d8bef9SDimitry Andric default:
3632e8d8bef9SDimitry Andric return false;
36330b57cec5SDimitry Andric }
36340b57cec5SDimitry Andric }
36350b57cec5SDimitry Andric
isStrictPredicate(Predicate pred)3636e8d8bef9SDimitry Andric bool CmpInst::isStrictPredicate(Predicate pred) {
3637e8d8bef9SDimitry Andric switch (pred) {
3638e8d8bef9SDimitry Andric case ICMP_SGT:
3639e8d8bef9SDimitry Andric case ICMP_SLT:
3640e8d8bef9SDimitry Andric case ICMP_UGT:
3641e8d8bef9SDimitry Andric case ICMP_ULT:
3642e8d8bef9SDimitry Andric case FCMP_OGT:
3643e8d8bef9SDimitry Andric case FCMP_OLT:
3644e8d8bef9SDimitry Andric case FCMP_UGT:
3645e8d8bef9SDimitry Andric case FCMP_ULT:
3646e8d8bef9SDimitry Andric return true;
3647e8d8bef9SDimitry Andric default:
3648e8d8bef9SDimitry Andric return false;
3649e8d8bef9SDimitry Andric }
3650e8d8bef9SDimitry Andric }
3651e8d8bef9SDimitry Andric
getStrictPredicate(Predicate pred)3652e8d8bef9SDimitry Andric CmpInst::Predicate CmpInst::getStrictPredicate(Predicate pred) {
3653e8d8bef9SDimitry Andric switch (pred) {
3654e8d8bef9SDimitry Andric case ICMP_SGE:
3655e8d8bef9SDimitry Andric return ICMP_SGT;
3656e8d8bef9SDimitry Andric case ICMP_SLE:
3657e8d8bef9SDimitry Andric return ICMP_SLT;
3658e8d8bef9SDimitry Andric case ICMP_UGE:
3659e8d8bef9SDimitry Andric return ICMP_UGT;
3660e8d8bef9SDimitry Andric case ICMP_ULE:
3661e8d8bef9SDimitry Andric return ICMP_ULT;
3662e8d8bef9SDimitry Andric case FCMP_OGE:
3663e8d8bef9SDimitry Andric return FCMP_OGT;
3664e8d8bef9SDimitry Andric case FCMP_OLE:
3665e8d8bef9SDimitry Andric return FCMP_OLT;
3666e8d8bef9SDimitry Andric case FCMP_UGE:
3667e8d8bef9SDimitry Andric return FCMP_UGT;
3668e8d8bef9SDimitry Andric case FCMP_ULE:
3669e8d8bef9SDimitry Andric return FCMP_ULT;
3670e8d8bef9SDimitry Andric default:
3671e8d8bef9SDimitry Andric return pred;
3672e8d8bef9SDimitry Andric }
3673e8d8bef9SDimitry Andric }
3674e8d8bef9SDimitry Andric
getNonStrictPredicate(Predicate pred)3675e8d8bef9SDimitry Andric CmpInst::Predicate CmpInst::getNonStrictPredicate(Predicate pred) {
3676e8d8bef9SDimitry Andric switch (pred) {
3677e8d8bef9SDimitry Andric case ICMP_SGT:
3678e8d8bef9SDimitry Andric return ICMP_SGE;
3679e8d8bef9SDimitry Andric case ICMP_SLT:
3680e8d8bef9SDimitry Andric return ICMP_SLE;
3681e8d8bef9SDimitry Andric case ICMP_UGT:
3682e8d8bef9SDimitry Andric return ICMP_UGE;
3683e8d8bef9SDimitry Andric case ICMP_ULT:
3684e8d8bef9SDimitry Andric return ICMP_ULE;
3685e8d8bef9SDimitry Andric case FCMP_OGT:
3686e8d8bef9SDimitry Andric return FCMP_OGE;
3687e8d8bef9SDimitry Andric case FCMP_OLT:
3688e8d8bef9SDimitry Andric return FCMP_OLE;
3689e8d8bef9SDimitry Andric case FCMP_UGT:
3690e8d8bef9SDimitry Andric return FCMP_UGE;
3691e8d8bef9SDimitry Andric case FCMP_ULT:
3692e8d8bef9SDimitry Andric return FCMP_ULE;
3693e8d8bef9SDimitry Andric default:
3694e8d8bef9SDimitry Andric return pred;
3695e8d8bef9SDimitry Andric }
3696e8d8bef9SDimitry Andric }
3697e8d8bef9SDimitry Andric
getFlippedStrictnessPredicate(Predicate pred)3698e8d8bef9SDimitry Andric CmpInst::Predicate CmpInst::getFlippedStrictnessPredicate(Predicate pred) {
3699e8d8bef9SDimitry Andric assert(CmpInst::isRelational(pred) && "Call only with relational predicate!");
3700e8d8bef9SDimitry Andric
3701e8d8bef9SDimitry Andric if (isStrictPredicate(pred))
3702e8d8bef9SDimitry Andric return getNonStrictPredicate(pred);
3703e8d8bef9SDimitry Andric if (isNonStrictPredicate(pred))
3704e8d8bef9SDimitry Andric return getStrictPredicate(pred);
3705e8d8bef9SDimitry Andric
3706e8d8bef9SDimitry Andric llvm_unreachable("Unknown predicate!");
3707e8d8bef9SDimitry Andric }
3708e8d8bef9SDimitry Andric
getSignedPredicate(Predicate pred)37090b57cec5SDimitry Andric CmpInst::Predicate CmpInst::getSignedPredicate(Predicate pred) {
3710e8d8bef9SDimitry Andric assert(CmpInst::isUnsigned(pred) && "Call only with unsigned predicates!");
37110b57cec5SDimitry Andric
37120b57cec5SDimitry Andric switch (pred) {
37130b57cec5SDimitry Andric default:
37140b57cec5SDimitry Andric llvm_unreachable("Unknown predicate!");
37150b57cec5SDimitry Andric case CmpInst::ICMP_ULT:
37160b57cec5SDimitry Andric return CmpInst::ICMP_SLT;
37170b57cec5SDimitry Andric case CmpInst::ICMP_ULE:
37180b57cec5SDimitry Andric return CmpInst::ICMP_SLE;
37190b57cec5SDimitry Andric case CmpInst::ICMP_UGT:
37200b57cec5SDimitry Andric return CmpInst::ICMP_SGT;
37210b57cec5SDimitry Andric case CmpInst::ICMP_UGE:
37220b57cec5SDimitry Andric return CmpInst::ICMP_SGE;
37230b57cec5SDimitry Andric }
37240b57cec5SDimitry Andric }
37250b57cec5SDimitry Andric
getUnsignedPredicate(Predicate pred)3726e8d8bef9SDimitry Andric CmpInst::Predicate CmpInst::getUnsignedPredicate(Predicate pred) {
3727e8d8bef9SDimitry Andric assert(CmpInst::isSigned(pred) && "Call only with signed predicates!");
3728e8d8bef9SDimitry Andric
3729e8d8bef9SDimitry Andric switch (pred) {
3730e8d8bef9SDimitry Andric default:
3731e8d8bef9SDimitry Andric llvm_unreachable("Unknown predicate!");
3732e8d8bef9SDimitry Andric case CmpInst::ICMP_SLT:
3733e8d8bef9SDimitry Andric return CmpInst::ICMP_ULT;
3734e8d8bef9SDimitry Andric case CmpInst::ICMP_SLE:
3735e8d8bef9SDimitry Andric return CmpInst::ICMP_ULE;
3736e8d8bef9SDimitry Andric case CmpInst::ICMP_SGT:
3737e8d8bef9SDimitry Andric return CmpInst::ICMP_UGT;
3738e8d8bef9SDimitry Andric case CmpInst::ICMP_SGE:
3739e8d8bef9SDimitry Andric return CmpInst::ICMP_UGE;
3740e8d8bef9SDimitry Andric }
3741e8d8bef9SDimitry Andric }
3742e8d8bef9SDimitry Andric
isUnsigned(Predicate predicate)37430b57cec5SDimitry Andric bool CmpInst::isUnsigned(Predicate predicate) {
37440b57cec5SDimitry Andric switch (predicate) {
37450b57cec5SDimitry Andric default: return false;
37460b57cec5SDimitry Andric case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: case ICmpInst::ICMP_UGT:
37470b57cec5SDimitry Andric case ICmpInst::ICMP_UGE: return true;
37480b57cec5SDimitry Andric }
37490b57cec5SDimitry Andric }
37500b57cec5SDimitry Andric
isSigned(Predicate predicate)37510b57cec5SDimitry Andric bool CmpInst::isSigned(Predicate predicate) {
37520b57cec5SDimitry Andric switch (predicate) {
37530b57cec5SDimitry Andric default: return false;
37540b57cec5SDimitry Andric case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_SLE: case ICmpInst::ICMP_SGT:
37550b57cec5SDimitry Andric case ICmpInst::ICMP_SGE: return true;
37560b57cec5SDimitry Andric }
37570b57cec5SDimitry Andric }
37580b57cec5SDimitry Andric
compare(const APInt & LHS,const APInt & RHS,ICmpInst::Predicate Pred)3759349cc55cSDimitry Andric bool ICmpInst::compare(const APInt &LHS, const APInt &RHS,
3760349cc55cSDimitry Andric ICmpInst::Predicate Pred) {
3761349cc55cSDimitry Andric assert(ICmpInst::isIntPredicate(Pred) && "Only for integer predicates!");
3762349cc55cSDimitry Andric switch (Pred) {
3763349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_EQ:
3764349cc55cSDimitry Andric return LHS.eq(RHS);
3765349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_NE:
3766349cc55cSDimitry Andric return LHS.ne(RHS);
3767349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_UGT:
3768349cc55cSDimitry Andric return LHS.ugt(RHS);
3769349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_UGE:
3770349cc55cSDimitry Andric return LHS.uge(RHS);
3771349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_ULT:
3772349cc55cSDimitry Andric return LHS.ult(RHS);
3773349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_ULE:
3774349cc55cSDimitry Andric return LHS.ule(RHS);
3775349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_SGT:
3776349cc55cSDimitry Andric return LHS.sgt(RHS);
3777349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_SGE:
3778349cc55cSDimitry Andric return LHS.sge(RHS);
3779349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_SLT:
3780349cc55cSDimitry Andric return LHS.slt(RHS);
3781349cc55cSDimitry Andric case ICmpInst::Predicate::ICMP_SLE:
3782349cc55cSDimitry Andric return LHS.sle(RHS);
3783349cc55cSDimitry Andric default:
3784349cc55cSDimitry Andric llvm_unreachable("Unexpected non-integer predicate.");
3785349cc55cSDimitry Andric };
3786349cc55cSDimitry Andric }
3787349cc55cSDimitry Andric
compare(const APFloat & LHS,const APFloat & RHS,FCmpInst::Predicate Pred)37880eae32dcSDimitry Andric bool FCmpInst::compare(const APFloat &LHS, const APFloat &RHS,
37890eae32dcSDimitry Andric FCmpInst::Predicate Pred) {
37900eae32dcSDimitry Andric APFloat::cmpResult R = LHS.compare(RHS);
37910eae32dcSDimitry Andric switch (Pred) {
37920eae32dcSDimitry Andric default:
37930eae32dcSDimitry Andric llvm_unreachable("Invalid FCmp Predicate");
37940eae32dcSDimitry Andric case FCmpInst::FCMP_FALSE:
37950eae32dcSDimitry Andric return false;
37960eae32dcSDimitry Andric case FCmpInst::FCMP_TRUE:
37970eae32dcSDimitry Andric return true;
37980eae32dcSDimitry Andric case FCmpInst::FCMP_UNO:
37990eae32dcSDimitry Andric return R == APFloat::cmpUnordered;
38000eae32dcSDimitry Andric case FCmpInst::FCMP_ORD:
38010eae32dcSDimitry Andric return R != APFloat::cmpUnordered;
38020eae32dcSDimitry Andric case FCmpInst::FCMP_UEQ:
38030eae32dcSDimitry Andric return R == APFloat::cmpUnordered || R == APFloat::cmpEqual;
38040eae32dcSDimitry Andric case FCmpInst::FCMP_OEQ:
38050eae32dcSDimitry Andric return R == APFloat::cmpEqual;
38060eae32dcSDimitry Andric case FCmpInst::FCMP_UNE:
38070eae32dcSDimitry Andric return R != APFloat::cmpEqual;
38080eae32dcSDimitry Andric case FCmpInst::FCMP_ONE:
38090eae32dcSDimitry Andric return R == APFloat::cmpLessThan || R == APFloat::cmpGreaterThan;
38100eae32dcSDimitry Andric case FCmpInst::FCMP_ULT:
38110eae32dcSDimitry Andric return R == APFloat::cmpUnordered || R == APFloat::cmpLessThan;
38120eae32dcSDimitry Andric case FCmpInst::FCMP_OLT:
38130eae32dcSDimitry Andric return R == APFloat::cmpLessThan;
38140eae32dcSDimitry Andric case FCmpInst::FCMP_UGT:
38150eae32dcSDimitry Andric return R == APFloat::cmpUnordered || R == APFloat::cmpGreaterThan;
38160eae32dcSDimitry Andric case FCmpInst::FCMP_OGT:
38170eae32dcSDimitry Andric return R == APFloat::cmpGreaterThan;
38180eae32dcSDimitry Andric case FCmpInst::FCMP_ULE:
38190eae32dcSDimitry Andric return R != APFloat::cmpGreaterThan;
38200eae32dcSDimitry Andric case FCmpInst::FCMP_OLE:
38210eae32dcSDimitry Andric return R == APFloat::cmpLessThan || R == APFloat::cmpEqual;
38220eae32dcSDimitry Andric case FCmpInst::FCMP_UGE:
38230eae32dcSDimitry Andric return R != APFloat::cmpLessThan;
38240eae32dcSDimitry Andric case FCmpInst::FCMP_OGE:
38250eae32dcSDimitry Andric return R == APFloat::cmpGreaterThan || R == APFloat::cmpEqual;
38260eae32dcSDimitry Andric }
38270eae32dcSDimitry Andric }
38280eae32dcSDimitry Andric
getFlippedSignednessPredicate(Predicate pred)3829e8d8bef9SDimitry Andric CmpInst::Predicate CmpInst::getFlippedSignednessPredicate(Predicate pred) {
3830e8d8bef9SDimitry Andric assert(CmpInst::isRelational(pred) &&
3831e8d8bef9SDimitry Andric "Call only with non-equality predicates!");
3832e8d8bef9SDimitry Andric
3833e8d8bef9SDimitry Andric if (isSigned(pred))
3834e8d8bef9SDimitry Andric return getUnsignedPredicate(pred);
3835e8d8bef9SDimitry Andric if (isUnsigned(pred))
3836e8d8bef9SDimitry Andric return getSignedPredicate(pred);
3837e8d8bef9SDimitry Andric
3838e8d8bef9SDimitry Andric llvm_unreachable("Unknown predicate!");
3839e8d8bef9SDimitry Andric }
3840e8d8bef9SDimitry Andric
isOrdered(Predicate predicate)38410b57cec5SDimitry Andric bool CmpInst::isOrdered(Predicate predicate) {
38420b57cec5SDimitry Andric switch (predicate) {
38430b57cec5SDimitry Andric default: return false;
38440b57cec5SDimitry Andric case FCmpInst::FCMP_OEQ: case FCmpInst::FCMP_ONE: case FCmpInst::FCMP_OGT:
38450b57cec5SDimitry Andric case FCmpInst::FCMP_OLT: case FCmpInst::FCMP_OGE: case FCmpInst::FCMP_OLE:
38460b57cec5SDimitry Andric case FCmpInst::FCMP_ORD: return true;
38470b57cec5SDimitry Andric }
38480b57cec5SDimitry Andric }
38490b57cec5SDimitry Andric
isUnordered(Predicate predicate)38500b57cec5SDimitry Andric bool CmpInst::isUnordered(Predicate predicate) {
38510b57cec5SDimitry Andric switch (predicate) {
38520b57cec5SDimitry Andric default: return false;
38530b57cec5SDimitry Andric case FCmpInst::FCMP_UEQ: case FCmpInst::FCMP_UNE: case FCmpInst::FCMP_UGT:
38540b57cec5SDimitry Andric case FCmpInst::FCMP_ULT: case FCmpInst::FCMP_UGE: case FCmpInst::FCMP_ULE:
38550b57cec5SDimitry Andric case FCmpInst::FCMP_UNO: return true;
38560b57cec5SDimitry Andric }
38570b57cec5SDimitry Andric }
38580b57cec5SDimitry Andric
isTrueWhenEqual(Predicate predicate)38590b57cec5SDimitry Andric bool CmpInst::isTrueWhenEqual(Predicate predicate) {
38600b57cec5SDimitry Andric switch(predicate) {
38610b57cec5SDimitry Andric default: return false;
38620b57cec5SDimitry Andric case ICMP_EQ: case ICMP_UGE: case ICMP_ULE: case ICMP_SGE: case ICMP_SLE:
38630b57cec5SDimitry Andric case FCMP_TRUE: case FCMP_UEQ: case FCMP_UGE: case FCMP_ULE: return true;
38640b57cec5SDimitry Andric }
38650b57cec5SDimitry Andric }
38660b57cec5SDimitry Andric
isFalseWhenEqual(Predicate predicate)38670b57cec5SDimitry Andric bool CmpInst::isFalseWhenEqual(Predicate predicate) {
38680b57cec5SDimitry Andric switch(predicate) {
38690b57cec5SDimitry Andric case ICMP_NE: case ICMP_UGT: case ICMP_ULT: case ICMP_SGT: case ICMP_SLT:
38700b57cec5SDimitry Andric case FCMP_FALSE: case FCMP_ONE: case FCMP_OGT: case FCMP_OLT: return true;
38710b57cec5SDimitry Andric default: return false;
38720b57cec5SDimitry Andric }
38730b57cec5SDimitry Andric }
38740b57cec5SDimitry Andric
isImpliedTrueByMatchingCmp(Predicate Pred1,Predicate Pred2)38750b57cec5SDimitry Andric bool CmpInst::isImpliedTrueByMatchingCmp(Predicate Pred1, Predicate Pred2) {
38760b57cec5SDimitry Andric // If the predicates match, then we know the first condition implies the
38770b57cec5SDimitry Andric // second is true.
38780b57cec5SDimitry Andric if (Pred1 == Pred2)
38790b57cec5SDimitry Andric return true;
38800b57cec5SDimitry Andric
38810b57cec5SDimitry Andric switch (Pred1) {
38820b57cec5SDimitry Andric default:
38830b57cec5SDimitry Andric break;
38840b57cec5SDimitry Andric case ICMP_EQ:
38850b57cec5SDimitry Andric // A == B implies A >=u B, A <=u B, A >=s B, and A <=s B are true.
38860b57cec5SDimitry Andric return Pred2 == ICMP_UGE || Pred2 == ICMP_ULE || Pred2 == ICMP_SGE ||
38870b57cec5SDimitry Andric Pred2 == ICMP_SLE;
38880b57cec5SDimitry Andric case ICMP_UGT: // A >u B implies A != B and A >=u B are true.
38890b57cec5SDimitry Andric return Pred2 == ICMP_NE || Pred2 == ICMP_UGE;
38900b57cec5SDimitry Andric case ICMP_ULT: // A <u B implies A != B and A <=u B are true.
38910b57cec5SDimitry Andric return Pred2 == ICMP_NE || Pred2 == ICMP_ULE;
38920b57cec5SDimitry Andric case ICMP_SGT: // A >s B implies A != B and A >=s B are true.
38930b57cec5SDimitry Andric return Pred2 == ICMP_NE || Pred2 == ICMP_SGE;
38940b57cec5SDimitry Andric case ICMP_SLT: // A <s B implies A != B and A <=s B are true.
38950b57cec5SDimitry Andric return Pred2 == ICMP_NE || Pred2 == ICMP_SLE;
38960b57cec5SDimitry Andric }
38970b57cec5SDimitry Andric return false;
38980b57cec5SDimitry Andric }
38990b57cec5SDimitry Andric
isImpliedFalseByMatchingCmp(Predicate Pred1,Predicate Pred2)39000b57cec5SDimitry Andric bool CmpInst::isImpliedFalseByMatchingCmp(Predicate Pred1, Predicate Pred2) {
39010b57cec5SDimitry Andric return isImpliedTrueByMatchingCmp(Pred1, getInversePredicate(Pred2));
39020b57cec5SDimitry Andric }
39030b57cec5SDimitry Andric
39040b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
39050b57cec5SDimitry Andric // SwitchInst Implementation
39060b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
39070b57cec5SDimitry Andric
init(Value * Value,BasicBlock * Default,unsigned NumReserved)39080b57cec5SDimitry Andric void SwitchInst::init(Value *Value, BasicBlock *Default, unsigned NumReserved) {
39090b57cec5SDimitry Andric assert(Value && Default && NumReserved);
39100b57cec5SDimitry Andric ReservedSpace = NumReserved;
39110b57cec5SDimitry Andric setNumHungOffUseOperands(2);
39120b57cec5SDimitry Andric allocHungoffUses(ReservedSpace);
39130b57cec5SDimitry Andric
39140b57cec5SDimitry Andric Op<0>() = Value;
39150b57cec5SDimitry Andric Op<1>() = Default;
39160b57cec5SDimitry Andric }
39170b57cec5SDimitry Andric
39180b57cec5SDimitry Andric /// SwitchInst ctor - Create a new switch instruction, specifying a value to
39190b57cec5SDimitry Andric /// switch on and a default destination. The number of additional cases can
39200b57cec5SDimitry Andric /// be specified here to make memory allocation more efficient. This
39210b57cec5SDimitry Andric /// constructor can also autoinsert before another instruction.
SwitchInst(Value * Value,BasicBlock * Default,unsigned NumCases,InsertPosition InsertBefore)39220b57cec5SDimitry Andric SwitchInst::SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
3923*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
39240b57cec5SDimitry Andric : Instruction(Type::getVoidTy(Value->getContext()), Instruction::Switch,
39250b57cec5SDimitry Andric nullptr, 0, InsertBefore) {
39260b57cec5SDimitry Andric init(Value, Default, 2+NumCases*2);
39270b57cec5SDimitry Andric }
39280b57cec5SDimitry Andric
SwitchInst(const SwitchInst & SI)39290b57cec5SDimitry Andric SwitchInst::SwitchInst(const SwitchInst &SI)
39300b57cec5SDimitry Andric : Instruction(SI.getType(), Instruction::Switch, nullptr, 0) {
39310b57cec5SDimitry Andric init(SI.getCondition(), SI.getDefaultDest(), SI.getNumOperands());
39320b57cec5SDimitry Andric setNumHungOffUseOperands(SI.getNumOperands());
39330b57cec5SDimitry Andric Use *OL = getOperandList();
39340b57cec5SDimitry Andric const Use *InOL = SI.getOperandList();
39350b57cec5SDimitry Andric for (unsigned i = 2, E = SI.getNumOperands(); i != E; i += 2) {
39360b57cec5SDimitry Andric OL[i] = InOL[i];
39370b57cec5SDimitry Andric OL[i+1] = InOL[i+1];
39380b57cec5SDimitry Andric }
39390b57cec5SDimitry Andric SubclassOptionalData = SI.SubclassOptionalData;
39400b57cec5SDimitry Andric }
39410b57cec5SDimitry Andric
39420b57cec5SDimitry Andric /// addCase - Add an entry to the switch instruction...
39430b57cec5SDimitry Andric ///
addCase(ConstantInt * OnVal,BasicBlock * Dest)39440b57cec5SDimitry Andric void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
39450b57cec5SDimitry Andric unsigned NewCaseIdx = getNumCases();
39460b57cec5SDimitry Andric unsigned OpNo = getNumOperands();
39470b57cec5SDimitry Andric if (OpNo+2 > ReservedSpace)
39480b57cec5SDimitry Andric growOperands(); // Get more space!
39490b57cec5SDimitry Andric // Initialize some new operands.
39500b57cec5SDimitry Andric assert(OpNo+1 < ReservedSpace && "Growing didn't work!");
39510b57cec5SDimitry Andric setNumHungOffUseOperands(OpNo+2);
39520b57cec5SDimitry Andric CaseHandle Case(this, NewCaseIdx);
39530b57cec5SDimitry Andric Case.setValue(OnVal);
39540b57cec5SDimitry Andric Case.setSuccessor(Dest);
39550b57cec5SDimitry Andric }
39560b57cec5SDimitry Andric
39570b57cec5SDimitry Andric /// removeCase - This method removes the specified case and its successor
39580b57cec5SDimitry Andric /// from the switch instruction.
removeCase(CaseIt I)39590b57cec5SDimitry Andric SwitchInst::CaseIt SwitchInst::removeCase(CaseIt I) {
39600b57cec5SDimitry Andric unsigned idx = I->getCaseIndex();
39610b57cec5SDimitry Andric
39620b57cec5SDimitry Andric assert(2 + idx*2 < getNumOperands() && "Case index out of range!!!");
39630b57cec5SDimitry Andric
39640b57cec5SDimitry Andric unsigned NumOps = getNumOperands();
39650b57cec5SDimitry Andric Use *OL = getOperandList();
39660b57cec5SDimitry Andric
39670b57cec5SDimitry Andric // Overwrite this case with the end of the list.
39680b57cec5SDimitry Andric if (2 + (idx + 1) * 2 != NumOps) {
39690b57cec5SDimitry Andric OL[2 + idx * 2] = OL[NumOps - 2];
39700b57cec5SDimitry Andric OL[2 + idx * 2 + 1] = OL[NumOps - 1];
39710b57cec5SDimitry Andric }
39720b57cec5SDimitry Andric
39730b57cec5SDimitry Andric // Nuke the last value.
39740b57cec5SDimitry Andric OL[NumOps-2].set(nullptr);
39750b57cec5SDimitry Andric OL[NumOps-2+1].set(nullptr);
39760b57cec5SDimitry Andric setNumHungOffUseOperands(NumOps-2);
39770b57cec5SDimitry Andric
39780b57cec5SDimitry Andric return CaseIt(this, idx);
39790b57cec5SDimitry Andric }
39800b57cec5SDimitry Andric
39810b57cec5SDimitry Andric /// growOperands - grow operands - This grows the operand list in response
39820b57cec5SDimitry Andric /// to a push_back style of operation. This grows the number of ops by 3 times.
39830b57cec5SDimitry Andric ///
growOperands()39840b57cec5SDimitry Andric void SwitchInst::growOperands() {
39850b57cec5SDimitry Andric unsigned e = getNumOperands();
39860b57cec5SDimitry Andric unsigned NumOps = e*3;
39870b57cec5SDimitry Andric
39880b57cec5SDimitry Andric ReservedSpace = NumOps;
39890b57cec5SDimitry Andric growHungoffUses(ReservedSpace);
39900b57cec5SDimitry Andric }
39910b57cec5SDimitry Andric
buildProfBranchWeightsMD()39920b57cec5SDimitry Andric MDNode *SwitchInstProfUpdateWrapper::buildProfBranchWeightsMD() {
39938bcb0991SDimitry Andric assert(Changed && "called only if metadata has changed");
39940b57cec5SDimitry Andric
39950b57cec5SDimitry Andric if (!Weights)
39960b57cec5SDimitry Andric return nullptr;
39970b57cec5SDimitry Andric
39980b57cec5SDimitry Andric assert(SI.getNumSuccessors() == Weights->size() &&
39990b57cec5SDimitry Andric "num of prof branch_weights must accord with num of successors");
40000b57cec5SDimitry Andric
4001bdd1243dSDimitry Andric bool AllZeroes = all_of(*Weights, [](uint32_t W) { return W == 0; });
40020b57cec5SDimitry Andric
4003bdd1243dSDimitry Andric if (AllZeroes || Weights->size() < 2)
40040b57cec5SDimitry Andric return nullptr;
40050b57cec5SDimitry Andric
40060b57cec5SDimitry Andric return MDBuilder(SI.getParent()->getContext()).createBranchWeights(*Weights);
40070b57cec5SDimitry Andric }
40080b57cec5SDimitry Andric
init()40090b57cec5SDimitry Andric void SwitchInstProfUpdateWrapper::init() {
4010bdd1243dSDimitry Andric MDNode *ProfileData = getBranchWeightMDNode(SI);
40118bcb0991SDimitry Andric if (!ProfileData)
40120b57cec5SDimitry Andric return;
40130b57cec5SDimitry Andric
4014*0fca6ea1SDimitry Andric if (getNumBranchWeights(*ProfileData) != SI.getNumSuccessors()) {
40150b57cec5SDimitry Andric llvm_unreachable("number of prof branch_weights metadata operands does "
40160b57cec5SDimitry Andric "not correspond to number of succesors");
40170b57cec5SDimitry Andric }
40180b57cec5SDimitry Andric
40190b57cec5SDimitry Andric SmallVector<uint32_t, 8> Weights;
4020bdd1243dSDimitry Andric if (!extractBranchWeights(ProfileData, Weights))
4021bdd1243dSDimitry Andric return;
40220b57cec5SDimitry Andric this->Weights = std::move(Weights);
40230b57cec5SDimitry Andric }
40240b57cec5SDimitry Andric
40250b57cec5SDimitry Andric SwitchInst::CaseIt
removeCase(SwitchInst::CaseIt I)40260b57cec5SDimitry Andric SwitchInstProfUpdateWrapper::removeCase(SwitchInst::CaseIt I) {
40270b57cec5SDimitry Andric if (Weights) {
40280b57cec5SDimitry Andric assert(SI.getNumSuccessors() == Weights->size() &&
40290b57cec5SDimitry Andric "num of prof branch_weights must accord with num of successors");
40308bcb0991SDimitry Andric Changed = true;
40310b57cec5SDimitry Andric // Copy the last case to the place of the removed one and shrink.
40320b57cec5SDimitry Andric // This is tightly coupled with the way SwitchInst::removeCase() removes
40330b57cec5SDimitry Andric // the cases in SwitchInst::removeCase(CaseIt).
4034bdd1243dSDimitry Andric (*Weights)[I->getCaseIndex() + 1] = Weights->back();
4035bdd1243dSDimitry Andric Weights->pop_back();
40360b57cec5SDimitry Andric }
40370b57cec5SDimitry Andric return SI.removeCase(I);
40380b57cec5SDimitry Andric }
40390b57cec5SDimitry Andric
addCase(ConstantInt * OnVal,BasicBlock * Dest,SwitchInstProfUpdateWrapper::CaseWeightOpt W)40400b57cec5SDimitry Andric void SwitchInstProfUpdateWrapper::addCase(
40410b57cec5SDimitry Andric ConstantInt *OnVal, BasicBlock *Dest,
40420b57cec5SDimitry Andric SwitchInstProfUpdateWrapper::CaseWeightOpt W) {
40430b57cec5SDimitry Andric SI.addCase(OnVal, Dest);
40440b57cec5SDimitry Andric
40450b57cec5SDimitry Andric if (!Weights && W && *W) {
40468bcb0991SDimitry Andric Changed = true;
40470b57cec5SDimitry Andric Weights = SmallVector<uint32_t, 8>(SI.getNumSuccessors(), 0);
4048bdd1243dSDimitry Andric (*Weights)[SI.getNumSuccessors() - 1] = *W;
40490b57cec5SDimitry Andric } else if (Weights) {
40508bcb0991SDimitry Andric Changed = true;
4051bdd1243dSDimitry Andric Weights->push_back(W.value_or(0));
40520b57cec5SDimitry Andric }
40530b57cec5SDimitry Andric if (Weights)
40540b57cec5SDimitry Andric assert(SI.getNumSuccessors() == Weights->size() &&
40550b57cec5SDimitry Andric "num of prof branch_weights must accord with num of successors");
40560b57cec5SDimitry Andric }
40570b57cec5SDimitry Andric
40585f757f3fSDimitry Andric Instruction::InstListType::iterator
eraseFromParent()40590b57cec5SDimitry Andric SwitchInstProfUpdateWrapper::eraseFromParent() {
40600b57cec5SDimitry Andric // Instruction is erased. Mark as unchanged to not touch it in the destructor.
40618bcb0991SDimitry Andric Changed = false;
40620b57cec5SDimitry Andric if (Weights)
40630b57cec5SDimitry Andric Weights->resize(0);
40640b57cec5SDimitry Andric return SI.eraseFromParent();
40650b57cec5SDimitry Andric }
40660b57cec5SDimitry Andric
40670b57cec5SDimitry Andric SwitchInstProfUpdateWrapper::CaseWeightOpt
getSuccessorWeight(unsigned idx)40680b57cec5SDimitry Andric SwitchInstProfUpdateWrapper::getSuccessorWeight(unsigned idx) {
40690b57cec5SDimitry Andric if (!Weights)
4070bdd1243dSDimitry Andric return std::nullopt;
407181ad6265SDimitry Andric return (*Weights)[idx];
40720b57cec5SDimitry Andric }
40730b57cec5SDimitry Andric
setSuccessorWeight(unsigned idx,SwitchInstProfUpdateWrapper::CaseWeightOpt W)40740b57cec5SDimitry Andric void SwitchInstProfUpdateWrapper::setSuccessorWeight(
40750b57cec5SDimitry Andric unsigned idx, SwitchInstProfUpdateWrapper::CaseWeightOpt W) {
40768bcb0991SDimitry Andric if (!W)
40770b57cec5SDimitry Andric return;
40780b57cec5SDimitry Andric
40790b57cec5SDimitry Andric if (!Weights && *W)
40800b57cec5SDimitry Andric Weights = SmallVector<uint32_t, 8>(SI.getNumSuccessors(), 0);
40810b57cec5SDimitry Andric
40820b57cec5SDimitry Andric if (Weights) {
408381ad6265SDimitry Andric auto &OldW = (*Weights)[idx];
40840b57cec5SDimitry Andric if (*W != OldW) {
40858bcb0991SDimitry Andric Changed = true;
40860b57cec5SDimitry Andric OldW = *W;
40870b57cec5SDimitry Andric }
40880b57cec5SDimitry Andric }
40890b57cec5SDimitry Andric }
40900b57cec5SDimitry Andric
40910b57cec5SDimitry Andric SwitchInstProfUpdateWrapper::CaseWeightOpt
getSuccessorWeight(const SwitchInst & SI,unsigned idx)40920b57cec5SDimitry Andric SwitchInstProfUpdateWrapper::getSuccessorWeight(const SwitchInst &SI,
40930b57cec5SDimitry Andric unsigned idx) {
4094bdd1243dSDimitry Andric if (MDNode *ProfileData = getBranchWeightMDNode(SI))
40950b57cec5SDimitry Andric if (ProfileData->getNumOperands() == SI.getNumSuccessors() + 1)
40960b57cec5SDimitry Andric return mdconst::extract<ConstantInt>(ProfileData->getOperand(idx + 1))
40970b57cec5SDimitry Andric ->getValue()
40980b57cec5SDimitry Andric .getZExtValue();
40990b57cec5SDimitry Andric
4100bdd1243dSDimitry Andric return std::nullopt;
41010b57cec5SDimitry Andric }
41020b57cec5SDimitry Andric
41030b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
41040b57cec5SDimitry Andric // IndirectBrInst Implementation
41050b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
41060b57cec5SDimitry Andric
init(Value * Address,unsigned NumDests)41070b57cec5SDimitry Andric void IndirectBrInst::init(Value *Address, unsigned NumDests) {
41080b57cec5SDimitry Andric assert(Address && Address->getType()->isPointerTy() &&
41090b57cec5SDimitry Andric "Address of indirectbr must be a pointer");
41100b57cec5SDimitry Andric ReservedSpace = 1+NumDests;
41110b57cec5SDimitry Andric setNumHungOffUseOperands(1);
41120b57cec5SDimitry Andric allocHungoffUses(ReservedSpace);
41130b57cec5SDimitry Andric
41140b57cec5SDimitry Andric Op<0>() = Address;
41150b57cec5SDimitry Andric }
41160b57cec5SDimitry Andric
41170b57cec5SDimitry Andric
41180b57cec5SDimitry Andric /// growOperands - grow operands - This grows the operand list in response
41190b57cec5SDimitry Andric /// to a push_back style of operation. This grows the number of ops by 2 times.
41200b57cec5SDimitry Andric ///
growOperands()41210b57cec5SDimitry Andric void IndirectBrInst::growOperands() {
41220b57cec5SDimitry Andric unsigned e = getNumOperands();
41230b57cec5SDimitry Andric unsigned NumOps = e*2;
41240b57cec5SDimitry Andric
41250b57cec5SDimitry Andric ReservedSpace = NumOps;
41260b57cec5SDimitry Andric growHungoffUses(ReservedSpace);
41270b57cec5SDimitry Andric }
41280b57cec5SDimitry Andric
IndirectBrInst(Value * Address,unsigned NumCases,InsertPosition InsertBefore)41290b57cec5SDimitry Andric IndirectBrInst::IndirectBrInst(Value *Address, unsigned NumCases,
4130*0fca6ea1SDimitry Andric InsertPosition InsertBefore)
41310b57cec5SDimitry Andric : Instruction(Type::getVoidTy(Address->getContext()),
41320b57cec5SDimitry Andric Instruction::IndirectBr, nullptr, 0, InsertBefore) {
41330b57cec5SDimitry Andric init(Address, NumCases);
41340b57cec5SDimitry Andric }
41350b57cec5SDimitry Andric
IndirectBrInst(const IndirectBrInst & IBI)41360b57cec5SDimitry Andric IndirectBrInst::IndirectBrInst(const IndirectBrInst &IBI)
41370b57cec5SDimitry Andric : Instruction(Type::getVoidTy(IBI.getContext()), Instruction::IndirectBr,
41380b57cec5SDimitry Andric nullptr, IBI.getNumOperands()) {
41390b57cec5SDimitry Andric allocHungoffUses(IBI.getNumOperands());
41400b57cec5SDimitry Andric Use *OL = getOperandList();
41410b57cec5SDimitry Andric const Use *InOL = IBI.getOperandList();
41420b57cec5SDimitry Andric for (unsigned i = 0, E = IBI.getNumOperands(); i != E; ++i)
41430b57cec5SDimitry Andric OL[i] = InOL[i];
41440b57cec5SDimitry Andric SubclassOptionalData = IBI.SubclassOptionalData;
41450b57cec5SDimitry Andric }
41460b57cec5SDimitry Andric
41470b57cec5SDimitry Andric /// addDestination - Add a destination.
41480b57cec5SDimitry Andric ///
addDestination(BasicBlock * DestBB)41490b57cec5SDimitry Andric void IndirectBrInst::addDestination(BasicBlock *DestBB) {
41500b57cec5SDimitry Andric unsigned OpNo = getNumOperands();
41510b57cec5SDimitry Andric if (OpNo+1 > ReservedSpace)
41520b57cec5SDimitry Andric growOperands(); // Get more space!
41530b57cec5SDimitry Andric // Initialize some new operands.
41540b57cec5SDimitry Andric assert(OpNo < ReservedSpace && "Growing didn't work!");
41550b57cec5SDimitry Andric setNumHungOffUseOperands(OpNo+1);
41560b57cec5SDimitry Andric getOperandList()[OpNo] = DestBB;
41570b57cec5SDimitry Andric }
41580b57cec5SDimitry Andric
41590b57cec5SDimitry Andric /// removeDestination - This method removes the specified successor from the
41600b57cec5SDimitry Andric /// indirectbr instruction.
removeDestination(unsigned idx)41610b57cec5SDimitry Andric void IndirectBrInst::removeDestination(unsigned idx) {
41620b57cec5SDimitry Andric assert(idx < getNumOperands()-1 && "Successor index out of range!");
41630b57cec5SDimitry Andric
41640b57cec5SDimitry Andric unsigned NumOps = getNumOperands();
41650b57cec5SDimitry Andric Use *OL = getOperandList();
41660b57cec5SDimitry Andric
41670b57cec5SDimitry Andric // Replace this value with the last one.
41680b57cec5SDimitry Andric OL[idx+1] = OL[NumOps-1];
41690b57cec5SDimitry Andric
41700b57cec5SDimitry Andric // Nuke the last value.
41710b57cec5SDimitry Andric OL[NumOps-1].set(nullptr);
41720b57cec5SDimitry Andric setNumHungOffUseOperands(NumOps-1);
41730b57cec5SDimitry Andric }
41740b57cec5SDimitry Andric
41750b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4176480093f4SDimitry Andric // FreezeInst Implementation
4177480093f4SDimitry Andric //===----------------------------------------------------------------------===//
4178480093f4SDimitry Andric
FreezeInst(Value * S,const Twine & Name,InsertPosition InsertBefore)4179*0fca6ea1SDimitry Andric FreezeInst::FreezeInst(Value *S, const Twine &Name, InsertPosition InsertBefore)
4180480093f4SDimitry Andric : UnaryInstruction(S->getType(), Freeze, S, InsertBefore) {
4181480093f4SDimitry Andric setName(Name);
4182480093f4SDimitry Andric }
4183480093f4SDimitry Andric
4184480093f4SDimitry Andric //===----------------------------------------------------------------------===//
41850b57cec5SDimitry Andric // cloneImpl() implementations
41860b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
41870b57cec5SDimitry Andric
41880b57cec5SDimitry Andric // Define these methods here so vtables don't get emitted into every translation
41890b57cec5SDimitry Andric // unit that uses these classes.
41900b57cec5SDimitry Andric
cloneImpl() const41910b57cec5SDimitry Andric GetElementPtrInst *GetElementPtrInst::cloneImpl() const {
41920b57cec5SDimitry Andric return new (getNumOperands()) GetElementPtrInst(*this);
41930b57cec5SDimitry Andric }
41940b57cec5SDimitry Andric
cloneImpl() const41950b57cec5SDimitry Andric UnaryOperator *UnaryOperator::cloneImpl() const {
41960b57cec5SDimitry Andric return Create(getOpcode(), Op<0>());
41970b57cec5SDimitry Andric }
41980b57cec5SDimitry Andric
cloneImpl() const41990b57cec5SDimitry Andric BinaryOperator *BinaryOperator::cloneImpl() const {
42000b57cec5SDimitry Andric return Create(getOpcode(), Op<0>(), Op<1>());
42010b57cec5SDimitry Andric }
42020b57cec5SDimitry Andric
cloneImpl() const42030b57cec5SDimitry Andric FCmpInst *FCmpInst::cloneImpl() const {
42040b57cec5SDimitry Andric return new FCmpInst(getPredicate(), Op<0>(), Op<1>());
42050b57cec5SDimitry Andric }
42060b57cec5SDimitry Andric
cloneImpl() const42070b57cec5SDimitry Andric ICmpInst *ICmpInst::cloneImpl() const {
42080b57cec5SDimitry Andric return new ICmpInst(getPredicate(), Op<0>(), Op<1>());
42090b57cec5SDimitry Andric }
42100b57cec5SDimitry Andric
cloneImpl() const42110b57cec5SDimitry Andric ExtractValueInst *ExtractValueInst::cloneImpl() const {
42120b57cec5SDimitry Andric return new ExtractValueInst(*this);
42130b57cec5SDimitry Andric }
42140b57cec5SDimitry Andric
cloneImpl() const42150b57cec5SDimitry Andric InsertValueInst *InsertValueInst::cloneImpl() const {
42160b57cec5SDimitry Andric return new InsertValueInst(*this);
42170b57cec5SDimitry Andric }
42180b57cec5SDimitry Andric
cloneImpl() const42190b57cec5SDimitry Andric AllocaInst *AllocaInst::cloneImpl() const {
4220bdd1243dSDimitry Andric AllocaInst *Result = new AllocaInst(getAllocatedType(), getAddressSpace(),
42215ffd83dbSDimitry Andric getOperand(0), getAlign());
42220b57cec5SDimitry Andric Result->setUsedWithInAlloca(isUsedWithInAlloca());
42230b57cec5SDimitry Andric Result->setSwiftError(isSwiftError());
42240b57cec5SDimitry Andric return Result;
42250b57cec5SDimitry Andric }
42260b57cec5SDimitry Andric
cloneImpl() const42270b57cec5SDimitry Andric LoadInst *LoadInst::cloneImpl() const {
42280b57cec5SDimitry Andric return new LoadInst(getType(), getOperand(0), Twine(), isVolatile(),
42295ffd83dbSDimitry Andric getAlign(), getOrdering(), getSyncScopeID());
42300b57cec5SDimitry Andric }
42310b57cec5SDimitry Andric
cloneImpl() const42320b57cec5SDimitry Andric StoreInst *StoreInst::cloneImpl() const {
42335ffd83dbSDimitry Andric return new StoreInst(getOperand(0), getOperand(1), isVolatile(), getAlign(),
42345ffd83dbSDimitry Andric getOrdering(), getSyncScopeID());
42350b57cec5SDimitry Andric }
42360b57cec5SDimitry Andric
cloneImpl() const42370b57cec5SDimitry Andric AtomicCmpXchgInst *AtomicCmpXchgInst::cloneImpl() const {
42385ffd83dbSDimitry Andric AtomicCmpXchgInst *Result = new AtomicCmpXchgInst(
42395ffd83dbSDimitry Andric getOperand(0), getOperand(1), getOperand(2), getAlign(),
42405ffd83dbSDimitry Andric getSuccessOrdering(), getFailureOrdering(), getSyncScopeID());
42410b57cec5SDimitry Andric Result->setVolatile(isVolatile());
42420b57cec5SDimitry Andric Result->setWeak(isWeak());
42430b57cec5SDimitry Andric return Result;
42440b57cec5SDimitry Andric }
42450b57cec5SDimitry Andric
cloneImpl() const42460b57cec5SDimitry Andric AtomicRMWInst *AtomicRMWInst::cloneImpl() const {
42470b57cec5SDimitry Andric AtomicRMWInst *Result =
42480b57cec5SDimitry Andric new AtomicRMWInst(getOperation(), getOperand(0), getOperand(1),
42495ffd83dbSDimitry Andric getAlign(), getOrdering(), getSyncScopeID());
42500b57cec5SDimitry Andric Result->setVolatile(isVolatile());
42510b57cec5SDimitry Andric return Result;
42520b57cec5SDimitry Andric }
42530b57cec5SDimitry Andric
cloneImpl() const42540b57cec5SDimitry Andric FenceInst *FenceInst::cloneImpl() const {
42550b57cec5SDimitry Andric return new FenceInst(getContext(), getOrdering(), getSyncScopeID());
42560b57cec5SDimitry Andric }
42570b57cec5SDimitry Andric
cloneImpl() const42580b57cec5SDimitry Andric TruncInst *TruncInst::cloneImpl() const {
42590b57cec5SDimitry Andric return new TruncInst(getOperand(0), getType());
42600b57cec5SDimitry Andric }
42610b57cec5SDimitry Andric
cloneImpl() const42620b57cec5SDimitry Andric ZExtInst *ZExtInst::cloneImpl() const {
42630b57cec5SDimitry Andric return new ZExtInst(getOperand(0), getType());
42640b57cec5SDimitry Andric }
42650b57cec5SDimitry Andric
cloneImpl() const42660b57cec5SDimitry Andric SExtInst *SExtInst::cloneImpl() const {
42670b57cec5SDimitry Andric return new SExtInst(getOperand(0), getType());
42680b57cec5SDimitry Andric }
42690b57cec5SDimitry Andric
cloneImpl() const42700b57cec5SDimitry Andric FPTruncInst *FPTruncInst::cloneImpl() const {
42710b57cec5SDimitry Andric return new FPTruncInst(getOperand(0), getType());
42720b57cec5SDimitry Andric }
42730b57cec5SDimitry Andric
cloneImpl() const42740b57cec5SDimitry Andric FPExtInst *FPExtInst::cloneImpl() const {
42750b57cec5SDimitry Andric return new FPExtInst(getOperand(0), getType());
42760b57cec5SDimitry Andric }
42770b57cec5SDimitry Andric
cloneImpl() const42780b57cec5SDimitry Andric UIToFPInst *UIToFPInst::cloneImpl() const {
42790b57cec5SDimitry Andric return new UIToFPInst(getOperand(0), getType());
42800b57cec5SDimitry Andric }
42810b57cec5SDimitry Andric
cloneImpl() const42820b57cec5SDimitry Andric SIToFPInst *SIToFPInst::cloneImpl() const {
42830b57cec5SDimitry Andric return new SIToFPInst(getOperand(0), getType());
42840b57cec5SDimitry Andric }
42850b57cec5SDimitry Andric
cloneImpl() const42860b57cec5SDimitry Andric FPToUIInst *FPToUIInst::cloneImpl() const {
42870b57cec5SDimitry Andric return new FPToUIInst(getOperand(0), getType());
42880b57cec5SDimitry Andric }
42890b57cec5SDimitry Andric
cloneImpl() const42900b57cec5SDimitry Andric FPToSIInst *FPToSIInst::cloneImpl() const {
42910b57cec5SDimitry Andric return new FPToSIInst(getOperand(0), getType());
42920b57cec5SDimitry Andric }
42930b57cec5SDimitry Andric
cloneImpl() const42940b57cec5SDimitry Andric PtrToIntInst *PtrToIntInst::cloneImpl() const {
42950b57cec5SDimitry Andric return new PtrToIntInst(getOperand(0), getType());
42960b57cec5SDimitry Andric }
42970b57cec5SDimitry Andric
cloneImpl() const42980b57cec5SDimitry Andric IntToPtrInst *IntToPtrInst::cloneImpl() const {
42990b57cec5SDimitry Andric return new IntToPtrInst(getOperand(0), getType());
43000b57cec5SDimitry Andric }
43010b57cec5SDimitry Andric
cloneImpl() const43020b57cec5SDimitry Andric BitCastInst *BitCastInst::cloneImpl() const {
43030b57cec5SDimitry Andric return new BitCastInst(getOperand(0), getType());
43040b57cec5SDimitry Andric }
43050b57cec5SDimitry Andric
cloneImpl() const43060b57cec5SDimitry Andric AddrSpaceCastInst *AddrSpaceCastInst::cloneImpl() const {
43070b57cec5SDimitry Andric return new AddrSpaceCastInst(getOperand(0), getType());
43080b57cec5SDimitry Andric }
43090b57cec5SDimitry Andric
cloneImpl() const43100b57cec5SDimitry Andric CallInst *CallInst::cloneImpl() const {
43110b57cec5SDimitry Andric if (hasOperandBundles()) {
43120b57cec5SDimitry Andric unsigned DescriptorBytes = getNumOperandBundles() * sizeof(BundleOpInfo);
43130b57cec5SDimitry Andric return new(getNumOperands(), DescriptorBytes) CallInst(*this);
43140b57cec5SDimitry Andric }
43150b57cec5SDimitry Andric return new(getNumOperands()) CallInst(*this);
43160b57cec5SDimitry Andric }
43170b57cec5SDimitry Andric
cloneImpl() const43180b57cec5SDimitry Andric SelectInst *SelectInst::cloneImpl() const {
43190b57cec5SDimitry Andric return SelectInst::Create(getOperand(0), getOperand(1), getOperand(2));
43200b57cec5SDimitry Andric }
43210b57cec5SDimitry Andric
cloneImpl() const43220b57cec5SDimitry Andric VAArgInst *VAArgInst::cloneImpl() const {
43230b57cec5SDimitry Andric return new VAArgInst(getOperand(0), getType());
43240b57cec5SDimitry Andric }
43250b57cec5SDimitry Andric
cloneImpl() const43260b57cec5SDimitry Andric ExtractElementInst *ExtractElementInst::cloneImpl() const {
43270b57cec5SDimitry Andric return ExtractElementInst::Create(getOperand(0), getOperand(1));
43280b57cec5SDimitry Andric }
43290b57cec5SDimitry Andric
cloneImpl() const43300b57cec5SDimitry Andric InsertElementInst *InsertElementInst::cloneImpl() const {
43310b57cec5SDimitry Andric return InsertElementInst::Create(getOperand(0), getOperand(1), getOperand(2));
43320b57cec5SDimitry Andric }
43330b57cec5SDimitry Andric
cloneImpl() const43340b57cec5SDimitry Andric ShuffleVectorInst *ShuffleVectorInst::cloneImpl() const {
43355ffd83dbSDimitry Andric return new ShuffleVectorInst(getOperand(0), getOperand(1), getShuffleMask());
43360b57cec5SDimitry Andric }
43370b57cec5SDimitry Andric
cloneImpl() const43380b57cec5SDimitry Andric PHINode *PHINode::cloneImpl() const { return new PHINode(*this); }
43390b57cec5SDimitry Andric
cloneImpl() const43400b57cec5SDimitry Andric LandingPadInst *LandingPadInst::cloneImpl() const {
43410b57cec5SDimitry Andric return new LandingPadInst(*this);
43420b57cec5SDimitry Andric }
43430b57cec5SDimitry Andric
cloneImpl() const43440b57cec5SDimitry Andric ReturnInst *ReturnInst::cloneImpl() const {
43450b57cec5SDimitry Andric return new(getNumOperands()) ReturnInst(*this);
43460b57cec5SDimitry Andric }
43470b57cec5SDimitry Andric
cloneImpl() const43480b57cec5SDimitry Andric BranchInst *BranchInst::cloneImpl() const {
43490b57cec5SDimitry Andric return new(getNumOperands()) BranchInst(*this);
43500b57cec5SDimitry Andric }
43510b57cec5SDimitry Andric
cloneImpl() const43520b57cec5SDimitry Andric SwitchInst *SwitchInst::cloneImpl() const { return new SwitchInst(*this); }
43530b57cec5SDimitry Andric
cloneImpl() const43540b57cec5SDimitry Andric IndirectBrInst *IndirectBrInst::cloneImpl() const {
43550b57cec5SDimitry Andric return new IndirectBrInst(*this);
43560b57cec5SDimitry Andric }
43570b57cec5SDimitry Andric
cloneImpl() const43580b57cec5SDimitry Andric InvokeInst *InvokeInst::cloneImpl() const {
43590b57cec5SDimitry Andric if (hasOperandBundles()) {
43600b57cec5SDimitry Andric unsigned DescriptorBytes = getNumOperandBundles() * sizeof(BundleOpInfo);
43610b57cec5SDimitry Andric return new(getNumOperands(), DescriptorBytes) InvokeInst(*this);
43620b57cec5SDimitry Andric }
43630b57cec5SDimitry Andric return new(getNumOperands()) InvokeInst(*this);
43640b57cec5SDimitry Andric }
43650b57cec5SDimitry Andric
cloneImpl() const43660b57cec5SDimitry Andric CallBrInst *CallBrInst::cloneImpl() const {
43670b57cec5SDimitry Andric if (hasOperandBundles()) {
43680b57cec5SDimitry Andric unsigned DescriptorBytes = getNumOperandBundles() * sizeof(BundleOpInfo);
43690b57cec5SDimitry Andric return new (getNumOperands(), DescriptorBytes) CallBrInst(*this);
43700b57cec5SDimitry Andric }
43710b57cec5SDimitry Andric return new (getNumOperands()) CallBrInst(*this);
43720b57cec5SDimitry Andric }
43730b57cec5SDimitry Andric
cloneImpl() const43740b57cec5SDimitry Andric ResumeInst *ResumeInst::cloneImpl() const { return new (1) ResumeInst(*this); }
43750b57cec5SDimitry Andric
cloneImpl() const43760b57cec5SDimitry Andric CleanupReturnInst *CleanupReturnInst::cloneImpl() const {
43770b57cec5SDimitry Andric return new (getNumOperands()) CleanupReturnInst(*this);
43780b57cec5SDimitry Andric }
43790b57cec5SDimitry Andric
cloneImpl() const43800b57cec5SDimitry Andric CatchReturnInst *CatchReturnInst::cloneImpl() const {
43810b57cec5SDimitry Andric return new (getNumOperands()) CatchReturnInst(*this);
43820b57cec5SDimitry Andric }
43830b57cec5SDimitry Andric
cloneImpl() const43840b57cec5SDimitry Andric CatchSwitchInst *CatchSwitchInst::cloneImpl() const {
43850b57cec5SDimitry Andric return new CatchSwitchInst(*this);
43860b57cec5SDimitry Andric }
43870b57cec5SDimitry Andric
cloneImpl() const43880b57cec5SDimitry Andric FuncletPadInst *FuncletPadInst::cloneImpl() const {
43890b57cec5SDimitry Andric return new (getNumOperands()) FuncletPadInst(*this);
43900b57cec5SDimitry Andric }
43910b57cec5SDimitry Andric
cloneImpl() const43920b57cec5SDimitry Andric UnreachableInst *UnreachableInst::cloneImpl() const {
43930b57cec5SDimitry Andric LLVMContext &Context = getContext();
43940b57cec5SDimitry Andric return new UnreachableInst(Context);
43950b57cec5SDimitry Andric }
4396480093f4SDimitry Andric
cloneImpl() const4397480093f4SDimitry Andric FreezeInst *FreezeInst::cloneImpl() const {
4398480093f4SDimitry Andric return new FreezeInst(getOperand(0));
4399480093f4SDimitry Andric }
4400