}
}
+/// getCopyFromRegs - If there was virtual register allocated for the value V
+/// emit CopyFromReg of the specified type Ty. Return empty SDValue() otherwise.
+SDValue SelectionDAGBuilder::getCopyFromRegs(const Value *V, Type *Ty) {
+ DenseMap<const Value *, unsigned>::iterator It = FuncInfo.ValueMap.find(V);
+ SDValue res;
+
+ if (It != FuncInfo.ValueMap.end()) {
+ unsigned InReg = It->second;
+ RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(), InReg,
+ Ty);
+ SDValue Chain = DAG.getEntryNode();
+ res = RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(), Chain, nullptr, V);
+ resolveDanglingDebugInfo(V, res);
+ }
+
+ return res;
+}
+
/// getValue - Return an SDValue for the given Value.
SDValue SelectionDAGBuilder::getValue(const Value *V) {
// If we already have an SDValue for this value, use it. It's important
// If there's a virtual register allocated and initialized for this
// value, use it.
- DenseMap<const Value *, unsigned>::iterator It = FuncInfo.ValueMap.find(V);
- if (It != FuncInfo.ValueMap.end()) {
- unsigned InReg = It->second;
- RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(), InReg,
- V->getType());
- SDValue Chain = DAG.getEntryNode();
- N = RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(), Chain, nullptr, V);
- resolveDanglingDebugInfo(V, N);
- return N;
+ SDValue copyFromReg = getCopyFromRegs(V, V->getType());
+ if (copyFromReg.getNode()) {
+ return copyFromReg;
}
// Otherwise create a new SDValue and remember it.
// Update machine-CFG edges.
MachineBasicBlock *Succ0MBB = FuncInfo.MBBMap[I.getSuccessor(0)];
- // Figure out which block is immediately after the current one.
- MachineBasicBlock *NextBlock = nullptr;
- MachineFunction::iterator BBI = BrMBB;
- if (++BBI != FuncInfo.MF->end())
- NextBlock = BBI;
-
if (I.isUnconditional()) {
// Update machine-CFG edges.
BrMBB->addSuccessor(Succ0MBB);
// If this is not a fall-through branch or optimizations are switched off,
// emit the branch.
- if (Succ0MBB != NextBlock || TM.getOptLevel() == CodeGenOpt::None)
+ if (Succ0MBB != NextBlock(BrMBB) || TM.getOptLevel() == CodeGenOpt::None)
DAG.setRoot(DAG.getNode(ISD::BR, getCurSDLoc(),
MVT::Other, getControlRoot(),
DAG.getBasicBlock(Succ0MBB)));
assert(CB.CC == ISD::SETLE && "Can handle only LE ranges now");
const APInt& Low = cast<ConstantInt>(CB.CmpLHS)->getValue();
- const APInt& High = cast<ConstantInt>(CB.CmpRHS)->getValue();
+ const APInt& High = cast<ConstantInt>(CB.CmpRHS)->getValue();
SDValue CmpOp = getValue(CB.CmpMHS);
EVT VT = CmpOp.getValueType();
if (CB.TrueBB != CB.FalseBB)
addSuccessorWithWeight(SwitchBB, CB.FalseBB, CB.FalseWeight);
- // Set NextBlock to be the MBB immediately after the current one, if any.
- // This is used to avoid emitting unnecessary branches to the next block.
- MachineBasicBlock *NextBlock = nullptr;
- MachineFunction::iterator BBI = SwitchBB;
- if (++BBI != FuncInfo.MF->end())
- NextBlock = BBI;
-
// If the lhs block is the next block, invert the condition so that we can
// fall through to the lhs instead of the rhs block.
- if (CB.TrueBB == NextBlock) {
+ if (CB.TrueBB == NextBlock(SwitchBB)) {
std::swap(CB.TrueBB, CB.FalseBB);
SDValue True = DAG.getConstant(1, Cond.getValueType());
Cond = DAG.getNode(ISD::XOR, dl, Cond.getValueType(), Cond, True);
Sub.getValueType()),
Sub, DAG.getConstant(JTH.Last - JTH.First, VT), ISD::SETUGT);
- // Set NextBlock to be the MBB immediately after the current one, if any.
- // This is used to avoid emitting unnecessary branches to the next block.
- MachineBasicBlock *NextBlock = nullptr;
- MachineFunction::iterator BBI = SwitchBB;
-
- if (++BBI != FuncInfo.MF->end())
- NextBlock = BBI;
-
SDValue BrCond = DAG.getNode(ISD::BRCOND, getCurSDLoc(),
MVT::Other, CopyTo, CMP,
DAG.getBasicBlock(JT.Default));
- if (JT.MBB != NextBlock)
+ // Avoid emitting unnecessary branches to the next block.
+ if (JT.MBB != NextBlock(SwitchBB))
BrCond = DAG.getNode(ISD::BR, getCurSDLoc(), MVT::Other, BrCond,
DAG.getBasicBlock(JT.MBB));
SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), getCurSDLoc(),
B.Reg, Sub);
- // Set NextBlock to be the MBB immediately after the current one, if any.
- // This is used to avoid emitting unnecessary branches to the next block.
- MachineBasicBlock *NextBlock = nullptr;
- MachineFunction::iterator BBI = SwitchBB;
- if (++BBI != FuncInfo.MF->end())
- NextBlock = BBI;
-
MachineBasicBlock* MBB = B.Cases[0].ThisBB;
addSuccessorWithWeight(SwitchBB, B.Default);
MVT::Other, CopyTo, RangeCmp,
DAG.getBasicBlock(B.Default));
- if (MBB != NextBlock)
+ // Avoid emitting unnecessary branches to the next block.
+ if (MBB != NextBlock(SwitchBB))
BrRange = DAG.getNode(ISD::BR, getCurSDLoc(), MVT::Other, CopyTo,
DAG.getBasicBlock(MBB));
MVT::Other, getControlRoot(),
Cmp, DAG.getBasicBlock(B.TargetBB));
- // Set NextBlock to be the MBB immediately after the current one, if any.
- // This is used to avoid emitting unnecessary branches to the next block.
- MachineBasicBlock *NextBlock = nullptr;
- MachineFunction::iterator BBI = SwitchBB;
- if (++BBI != FuncInfo.MF->end())
- NextBlock = BBI;
-
- if (NextMBB != NextBlock)
+ // Avoid emitting unnecessary branches to the next block.
+ if (NextMBB != NextBlock(SwitchBB))
BrAnd = DAG.getNode(ISD::BR, getCurSDLoc(), MVT::Other, BrAnd,
DAG.getBasicBlock(NextMBB));
case Intrinsic::experimental_patchpoint_i64:
visitPatchpoint(&I, LandingPad);
break;
+ case Intrinsic::experimental_gc_statepoint:
+ LowerStatepoint(ImmutableStatepoint(&I), LandingPad);
+ break;
}
} else
LowerCallTo(&I, getValue(Callee), false, LandingPad);
// If the value of the invoke is used outside of its defining block, make it
// available as a virtual register.
- CopyToExportRegsIfNeeded(&I);
+ // We already took care of the exported value for the statepoint instruction
+ // during call to the LowerStatepoint.
+ if (!isStatepoint(I)) {
+ CopyToExportRegsIfNeeded(&I);
+ }
// Update successor info
addSuccessorWithWeight(InvokeMBB, Return);
MachineFunction *CurMF = FuncInfo.MF;
// Figure out which block is immediately after the current one.
- MachineBasicBlock *NextBlock = nullptr;
+ MachineBasicBlock *NextMBB = nullptr;
MachineFunction::iterator BBI = CR.CaseBB;
-
if (++BBI != FuncInfo.MF->end())
- NextBlock = BBI;
+ NextMBB = BBI;
BranchProbabilityInfo *BPI = FuncInfo.BPI;
// If any two of the cases has the same destination, and if one value
Case &Big = *(CR.Range.second-1);
if (Small.Low == Small.High && Big.Low == Big.High && Small.BB == Big.BB) {
- const APInt& SmallValue = cast<ConstantInt>(Small.Low)->getValue();
- const APInt& BigValue = cast<ConstantInt>(Big.Low)->getValue();
+ const APInt& SmallValue = Small.Low->getValue();
+ const APInt& BigValue = Big.Low->getValue();
// Check that there is only one bit different.
if (BigValue.countPopulation() == SmallValue.countPopulation() + 1 &&
}
// Rearrange the case blocks so that the last one falls through if possible.
Case &BackCase = *(CR.Range.second-1);
- if (Size > 1 &&
- NextBlock && Default != NextBlock && BackCase.BB != NextBlock) {
- // The last case block won't fall through into 'NextBlock' if we emit the
+ if (Size > 1 && NextMBB && Default != NextMBB && BackCase.BB != NextMBB) {
+ // The last case block won't fall through into 'NextMBB' if we emit the
// branches in this order. See if rearranging a case value would help.
// We start at the bottom as it's the case with the least weight.
for (Case *I = &*(CR.Range.second-2), *E = &*CR.Range.first-1; I != E; --I)
- if (I->BB == NextBlock) {
+ if (I->BB == NextMBB) {
std::swap(*I, BackCase);
break;
}
Case& FrontCase = *CR.Range.first;
Case& BackCase = *(CR.Range.second-1);
- const APInt &First = cast<ConstantInt>(FrontCase.Low)->getValue();
- const APInt &Last = cast<ConstantInt>(BackCase.High)->getValue();
+ const APInt &First = FrontCase.Low->getValue();
+ const APInt &Last = BackCase.High->getValue();
APInt TSize(First.getBitWidth(), 0);
for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++I)
std::vector<MachineBasicBlock*> DestBBs;
APInt TEI = First;
for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++TEI) {
- const APInt &Low = cast<ConstantInt>(I->Low)->getValue();
- const APInt &High = cast<ConstantInt>(I->High)->getValue();
+ const APInt &Low = I->Low->getValue();
+ const APInt &High = I->High->getValue();
if (Low.sle(TEI) && TEI.sle(High)) {
DestBBs.push_back(I->BB);
// Calculate weight for each unique destination in CR.
DenseMap<MachineBasicBlock*, uint32_t> DestWeights;
- if (FuncInfo.BPI)
- for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++I) {
- DenseMap<MachineBasicBlock*, uint32_t>::iterator Itr =
- DestWeights.find(I->BB);
- if (Itr != DestWeights.end())
- Itr->second += I->ExtraWeight;
- else
- DestWeights[I->BB] = I->ExtraWeight;
- }
+ if (FuncInfo.BPI) {
+ for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++I)
+ DestWeights[I->BB] += I->ExtraWeight;
+ }
// Update successor info. Add one edge to each unique successor.
BitVector SuccsHandled(CR.CaseBB->getParent()->getNumBlockIDs());
- for (std::vector<MachineBasicBlock*>::iterator I = DestBBs.begin(),
- E = DestBBs.end(); I != E; ++I) {
- if (!SuccsHandled[(*I)->getNumber()]) {
- SuccsHandled[(*I)->getNumber()] = true;
- DenseMap<MachineBasicBlock*, uint32_t>::iterator Itr =
- DestWeights.find(*I);
- addSuccessorWithWeight(JumpTableBB, *I,
- Itr != DestWeights.end() ? Itr->second : 0);
+ for (MachineBasicBlock *DestBB : DestBBs) {
+ if (!SuccsHandled[DestBB->getNumber()]) {
+ SuccsHandled[DestBB->getNumber()] = true;
+ auto I = DestWeights.find(DestBB);
+ addSuccessorWithWeight(JumpTableBB, DestBB,
+ I != DestWeights.end() ? I->second : 0);
}
}
// Size is the number of Cases represented by this range.
unsigned Size = CR.Range.second - CR.Range.first;
- const APInt &First = cast<ConstantInt>(FrontCase.Low)->getValue();
- const APInt &Last = cast<ConstantInt>(BackCase.High)->getValue();
+ const APInt &First = FrontCase.Low->getValue();
+ const APInt &Last = BackCase.High->getValue();
double FMetric = 0;
CaseItr Pivot = CR.Range.first + Size/2;
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
for (CaseItr I = CR.Range.first, J=I+1, E = CR.Range.second;
J!=E; ++I, ++J) {
- const APInt &LEnd = cast<ConstantInt>(I->High)->getValue();
- const APInt &RBegin = cast<ConstantInt>(J->Low)->getValue();
+ const APInt &LEnd = I->High->getValue();
+ const APInt &RBegin = J->Low->getValue();
APInt Range = ComputeRange(LEnd, RBegin);
assert((Range - 2ULL).isNonNegative() &&
"Invalid case distance");
CaseRange LHSR(CR.Range.first, Pivot);
CaseRange RHSR(Pivot, CR.Range.second);
- const Constant *C = Pivot->Low;
+ const ConstantInt *C = Pivot->Low;
MachineBasicBlock *FalseBB = nullptr, *TrueBB = nullptr;
// We know that we branch to the LHS if the Value being switched on is
// Pivot's Value, then we can branch directly to the LHS's Target,
// rather than creating a leaf node for it.
if ((LHSR.second - LHSR.first) == 1 && LHSR.first->High == CR.GE &&
- cast<ConstantInt>(C)->getValue() ==
- (cast<ConstantInt>(CR.GE)->getValue() + 1LL)) {
+ C->getValue() == (CR.GE->getValue() + 1LL)) {
TrueBB = LHSR.first->BB;
} else {
TrueBB = CurMF->CreateMachineBasicBlock(LLVMBB);
// is CR.LT - 1, then we can branch directly to the target block for
// the current Case Value, rather than emitting a RHS leaf node for it.
if ((RHSR.second - RHSR.first) == 1 && CR.LT &&
- cast<ConstantInt>(RHSR.first->Low)->getValue() ==
- (cast<ConstantInt>(CR.LT)->getValue() - 1LL)) {
+ RHSR.first->Low->getValue() == (CR.LT->getValue() - 1LL)) {
FalseBB = RHSR.first->BB;
} else {
FalseBB = CurMF->CreateMachineBasicBlock(LLVMBB);
<< "Total number of comparisons: " << numCmps << '\n');
// Compute span of values.
- const APInt& minValue = cast<ConstantInt>(FrontCase.Low)->getValue();
- const APInt& maxValue = cast<ConstantInt>(BackCase.High)->getValue();
+ const APInt& minValue = FrontCase.Low->getValue();
+ const APInt& maxValue = BackCase.High->getValue();
APInt cmpRange = maxValue - minValue;
DEBUG(dbgs() << "Compare range: " << cmpRange << '\n'
count++;
}
- const APInt& lowValue = cast<ConstantInt>(I->Low)->getValue();
- const APInt& highValue = cast<ConstantInt>(I->High)->getValue();
+ const APInt& lowValue = I->Low->getValue();
+ const APInt& highValue = I->High->getValue();
uint64_t lo = (lowValue - lowBound).getZExtValue();
uint64_t hi = (highValue - lowBound).getZExtValue();
return true;
}
-/// Clusterify - Transform simple list of Cases into list of CaseRange's
-void SelectionDAGBuilder::Clusterify(CaseVector& Cases,
- const SwitchInst& SI) {
+void SelectionDAGBuilder::Clusterify(CaseVector &Cases, const SwitchInst *SI) {
BranchProbabilityInfo *BPI = FuncInfo.BPI;
- // Start with "simple" cases.
- for (SwitchInst::ConstCaseIt i : SI.cases()) {
- const BasicBlock *SuccBB = i.getCaseSuccessor();
- MachineBasicBlock *SMBB = FuncInfo.MBBMap[SuccBB];
-
- uint32_t ExtraWeight =
- BPI ? BPI->getEdgeWeight(SI.getParent(), i.getSuccessorIndex()) : 0;
-
- Cases.push_back(Case(i.getCaseValue(), i.getCaseValue(),
- SMBB, ExtraWeight));
- }
- std::sort(Cases.begin(), Cases.end(), CaseCmp());
-
- // Merge case into clusters
- if (Cases.size() >= 2)
- // Must recompute end() each iteration because it may be
- // invalidated by erase if we hold on to it
- for (CaseItr I = Cases.begin(), J = std::next(Cases.begin());
- J != Cases.end(); ) {
- const APInt& nextValue = cast<ConstantInt>(J->Low)->getValue();
- const APInt& currentValue = cast<ConstantInt>(I->High)->getValue();
- MachineBasicBlock* nextBB = J->BB;
- MachineBasicBlock* currentBB = I->BB;
-
- // If the two neighboring cases go to the same destination, merge them
- // into a single case.
- if ((nextValue - currentValue == 1) && (currentBB == nextBB)) {
- I->High = J->High;
- I->ExtraWeight += J->ExtraWeight;
- J = Cases.erase(J);
- } else {
- I = J++;
- }
+
+ // Extract cases from the switch and sort them.
+ typedef std::pair<const ConstantInt*, unsigned> CasePair;
+ std::vector<CasePair> Sorted;
+ Sorted.reserve(SI->getNumCases());
+ for (auto I : SI->cases())
+ Sorted.push_back(std::make_pair(I.getCaseValue(), I.getSuccessorIndex()));
+ std::sort(Sorted.begin(), Sorted.end(), [](CasePair a, CasePair b) {
+ return a.first->getValue().slt(b.first->getValue());
+ });
+
+ // Merge adjacent cases with the same destination, build Cases vector.
+ assert(Cases.empty() && "Cases should be empty before Clusterify;");
+ Cases.reserve(SI->getNumCases());
+ MachineBasicBlock *PreviousSucc = nullptr;
+ for (CasePair &CP : Sorted) {
+ const ConstantInt *CaseVal = CP.first;
+ unsigned SuccIndex = CP.second;
+ MachineBasicBlock *Succ = FuncInfo.MBBMap[SI->getSuccessor(SuccIndex)];
+ uint32_t Weight = BPI ? BPI->getEdgeWeight(SI->getParent(), SuccIndex) : 0;
+
+ if (PreviousSucc == Succ &&
+ (CaseVal->getValue() - Cases.back().High->getValue()) == 1) {
+ // If this case has the same successor and is a neighbour, merge it into
+ // the previous cluster.
+ Cases.back().High = CaseVal;
+ Cases.back().ExtraWeight += Weight;
+ } else {
+ Cases.push_back(Case(CaseVal, CaseVal, Succ, Weight));
}
+ PreviousSucc = Succ;
+ }
+
DEBUG({
size_t numCmps = 0;
for (auto &I : Cases)
void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) {
MachineBasicBlock *SwitchMBB = FuncInfo.MBB;
- // Figure out which block is immediately after the current one.
- MachineBasicBlock *NextBlock = nullptr;
- if (SwitchMBB + 1 != FuncInfo.MF->end())
- NextBlock = SwitchMBB + 1;
-
-
// Create a vector of Cases, sorted so that we can efficiently create a binary
// search tree from them.
CaseVector Cases;
- Clusterify(Cases, SI);
+ Clusterify(Cases, &SI);
// Get the default destination MBB.
MachineBasicBlock *Default = FuncInfo.MBBMap[SI.getDefaultDest()];
SwitchMBB->addSuccessor(Default);
// If this is not a fall-through branch, emit the branch.
- if (Default != NextBlock) {
+ if (Default != NextBlock(SwitchMBB)) {
DAG.setRoot(DAG.getNode(ISD::BR, getCurSDLoc(), MVT::Other,
getControlRoot(), DAG.getBasicBlock(Default)));
}
Ty = StTy->getElementType(Field);
} else {
Ty = cast<SequentialType>(Ty)->getElementType();
+ MVT PtrTy = DAG.getTargetLoweringInfo().getPointerTy(AS);
+ unsigned PtrSize = PtrTy.getSizeInBits();
+ APInt ElementSize(PtrSize, DL->getTypeAllocSize(Ty));
// If this is a constant subscript, handle it quickly.
- const TargetLowering &TLI = DAG.getTargetLoweringInfo();
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(Idx)) {
- if (CI->isZero()) continue;
- uint64_t Offs =
- DL->getTypeAllocSize(Ty)*cast<ConstantInt>(CI)->getSExtValue();
- SDValue OffsVal;
- EVT PTy = TLI.getPointerTy(AS);
- unsigned PtrBits = PTy.getSizeInBits();
- if (PtrBits < 64)
- OffsVal = DAG.getNode(ISD::TRUNCATE, getCurSDLoc(), PTy,
- DAG.getConstant(Offs, MVT::i64));
- else
- OffsVal = DAG.getConstant(Offs, PTy);
-
- N = DAG.getNode(ISD::ADD, getCurSDLoc(), N.getValueType(), N,
- OffsVal);
+ if (const auto *CI = dyn_cast<ConstantInt>(Idx)) {
+ if (CI->isZero())
+ continue;
+ APInt Offs = ElementSize * CI->getValue().sextOrTrunc(PtrSize);
+ SDValue OffsVal = DAG.getConstant(Offs, PtrTy);
+ N = DAG.getNode(ISD::ADD, getCurSDLoc(), N.getValueType(), N, OffsVal);
continue;
}
// N = N + Idx * ElementSize;
- APInt ElementSize =
- APInt(TLI.getPointerSizeInBits(AS), DL->getTypeAllocSize(Ty));
SDValue IdxN = getValue(Idx);
// If the index is smaller or larger than intptr_t, truncate or extend
setValue(&I, Res);
return nullptr;
}
- case Intrinsic::x86_avx_vinsertf128_pd_256:
- case Intrinsic::x86_avx_vinsertf128_ps_256:
- case Intrinsic::x86_avx_vinsertf128_si_256:
- case Intrinsic::x86_avx2_vinserti128: {
- EVT DestVT = TLI.getValueType(I.getType());
- EVT ElVT = TLI.getValueType(I.getArgOperand(1)->getType());
- uint64_t Idx = (cast<ConstantInt>(I.getArgOperand(2))->getZExtValue() & 1) *
- ElVT.getVectorNumElements();
- Res =
- DAG.getNode(ISD::INSERT_SUBVECTOR, sdl, DestVT,
- getValue(I.getArgOperand(0)), getValue(I.getArgOperand(1)),
- DAG.getConstant(Idx, TLI.getVectorIdxTy()));
- setValue(&I, Res);
- return nullptr;
- }
- case Intrinsic::x86_avx_vextractf128_pd_256:
- case Intrinsic::x86_avx_vextractf128_ps_256:
- case Intrinsic::x86_avx_vextractf128_si_256:
- case Intrinsic::x86_avx2_vextracti128: {
- EVT DestVT = TLI.getValueType(I.getType());
- uint64_t Idx = (cast<ConstantInt>(I.getArgOperand(1))->getZExtValue() & 1) *
- DestVT.getVectorNumElements();
- Res = DAG.getNode(ISD::EXTRACT_SUBVECTOR, sdl, DestVT,
- getValue(I.getArgOperand(0)),
- DAG.getConstant(Idx, TLI.getVectorIdxTy()));
- setValue(&I, Res);
- return nullptr;
- }
case Intrinsic::convertff:
case Intrinsic::convertfsi:
case Intrinsic::convertfui:
// Memory output, or 'other' output (e.g. 'X' constraint).
assert(OpInfo.isIndirect && "Memory output must be indirect operand");
+ unsigned ConstraintID =
+ TLI.getInlineAsmMemConstraint(OpInfo.ConstraintCode);
+ assert(ConstraintID != InlineAsm::Constraint_Unknown &&
+ "Failed to convert memory constraint code to constraint id.");
+
// Add information to the INLINEASM node to know about this output.
unsigned OpFlags = InlineAsm::getFlagWord(InlineAsm::Kind_Mem, 1);
- AsmNodeOperands.push_back(DAG.getTargetConstant(OpFlags,
- TLI.getPointerTy()));
+ OpFlags = InlineAsm::getFlagWordForMem(OpFlags, ConstraintID);
+ AsmNodeOperands.push_back(DAG.getTargetConstant(OpFlags, MVT::i32));
AsmNodeOperands.push_back(OpInfo.CallOperand);
break;
}
"Unexpected number of operands");
// Add information to the INLINEASM node to know about this input.
// See InlineAsm.h isUseOperandTiedToDef.
+ OpFlag = InlineAsm::convertMemFlagWordToMatchingFlagWord(OpFlag);
OpFlag = InlineAsm::getFlagWordForMatchingOp(OpFlag,
OpInfo.getMatchedOperand());
AsmNodeOperands.push_back(DAG.getTargetConstant(OpFlag,
assert(InOperandVal.getValueType() == TLI.getPointerTy() &&
"Memory operands expect pointer values");
+ unsigned ConstraintID =
+ TLI.getInlineAsmMemConstraint(OpInfo.ConstraintCode);
+ assert(ConstraintID != InlineAsm::Constraint_Unknown &&
+ "Failed to convert memory constraint code to constraint id.");
+
// Add information to the INLINEASM node to know about this input.
unsigned ResOpType = InlineAsm::getFlagWord(InlineAsm::Kind_Mem, 1);
- AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType,
- TLI.getPointerTy()));
+ ResOpType = InlineAsm::getFlagWordForMem(ResOpType, ConstraintID);
+ AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType, MVT::i32));
AsmNodeOperands.push_back(InOperandVal);
break;
}
SmallPtrSet<MachineBasicBlock *, 4> SuccsHandled;
- // Check successor nodes' PHI nodes that expect a constant to be available
- // from this block.
+ // Check PHI nodes in successors that expect a value to be available from this
+ // block.
for (unsigned succ = 0, e = TI->getNumSuccessors(); succ != e; ++succ) {
const BasicBlock *SuccBB = TI->getSuccessor(succ);
if (!isa<PHINode>(SuccBB->begin())) continue;
SuccMBB, BranchProbabilityInfo::getBranchWeightStackProtector(IsLikely));
return SuccMBB;
}
+
+MachineBasicBlock *SelectionDAGBuilder::NextBlock(MachineBasicBlock *MBB) {
+ MachineFunction::iterator I = MBB;
+ if (++I == FuncInfo.MF->end())
+ return nullptr;
+ return I;
+}