Let callers decide the sub-register index on the def operand of rematerialized instructions.

Avoid remat'ing instructions whose def have sub-register indices for now. It's just really really hard to get all the cases right.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75900 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2009-07-16 09:20:10 +00:00
parent 6ef40b11f8
commit 378445303b
20 changed files with 277 additions and 49 deletions

View File

@ -151,7 +151,7 @@ public:
/// specific location targeting a new destination register.
virtual void reMaterialize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned DestReg,
unsigned DestReg, unsigned SubIdx,
const MachineInstr *Orig) const = 0;
/// isInvariantLoad - Return true if the specified instruction (which is
@ -499,7 +499,7 @@ public:
const SmallVectorImpl<MachineOperand> &Pred) const;
virtual void reMaterialize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned DestReg,
unsigned DestReg, unsigned SubReg,
const MachineInstr *Orig) const;
virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const;
};

View File

@ -1157,6 +1157,11 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li,
if (DisableReMat)
return false;
// FIXME: For now, avoid remating instructions whose definition has a subreg
// index. It's just incredibly difficult to get right.
if (MI->findRegisterDefOperand(li.reg)->getSubReg())
return false;
if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
return true;
@ -1595,7 +1600,7 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
if (CreatedNewVReg) {
if (DefIsReMat) {
vrm.setVirtIsReMaterialized(NewVReg, ReMatDefMI/*, CanDelete*/);
vrm.setVirtIsReMaterialized(NewVReg, ReMatDefMI);
if (ReMatIds[VNI->id] == VirtRegMap::MAX_STACK_SLOT) {
// Each valnum may have its own remat id.
ReMatIds[VNI->id] = vrm.assignVirtReMatId(NewVReg);

View File

@ -867,7 +867,7 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) {
NumRenumbers++;
}
bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo,
bool PreAllocSplitting::Rematerialize(unsigned VReg, VNInfo* ValNo,
MachineInstr* DefMI,
MachineBasicBlock::iterator RestorePt,
unsigned RestoreIdx,
@ -884,7 +884,7 @@ bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo,
if (KillPt == DefMI->getParent()->end())
return false;
TII->reMaterialize(MBB, RestorePt, vreg, DefMI);
TII->reMaterialize(MBB, RestorePt, VReg, 0, DefMI);
LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx);
ReconstructLiveInterval(CurrLI);

View File

@ -590,6 +590,7 @@ SimpleRegisterCoalescing::TrimLiveIntervalToLastUse(unsigned CopyIdx,
/// computation, replace the copy by rematerialize the definition.
bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
unsigned DstReg,
unsigned DstSubIdx,
MachineInstr *CopyMI) {
unsigned CopyIdx = li_->getUseIndex(li_->getInstructionIndex(CopyMI));
LiveInterval::iterator SrcLR = SrcInt.FindLiveRangeContaining(CopyIdx);
@ -647,7 +648,7 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
}
MachineBasicBlock::iterator MII = next(MachineBasicBlock::iterator(CopyMI));
tii_->reMaterialize(*MBB, MII, DstReg, DefMI);
tii_->reMaterialize(*MBB, MII, DstReg, DstSubIdx, DefMI);
MachineInstr *NewMI = prior(MII);
if (checkForDeadDef) {
@ -738,7 +739,8 @@ SimpleRegisterCoalescing::UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg,
CopySrcReg == SrcReg && CopyDstReg != UseDstReg) {
// If the use is a copy and it won't be coalesced away, and its source
// is defined by a trivial computation, try to rematerialize it instead.
if (ReMaterializeTrivialDef(li_->getInterval(SrcReg), CopyDstReg,UseMI))
if (ReMaterializeTrivialDef(li_->getInterval(SrcReg), CopyDstReg,
CopyDstSubIdx, UseMI))
continue;
}
@ -950,10 +952,9 @@ SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li,
if (LR->valno->def == RemoveStart) {
// If the def MI defines the val# and this copy is the only kill of the
// val#, then propagate the dead marker.
if (li.isOnlyLROfValNo(LR)) {
PropagateDeadness(li, CopyMI, RemoveStart, li_, tri_);
++numDeadValNo;
}
PropagateDeadness(li, CopyMI, RemoveStart, li_, tri_);
++numDeadValNo;
if (li.isKill(LR->valno, RemoveEnd))
li.removeKill(LR->valno, RemoveEnd);
}
@ -1679,7 +1680,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
// If definition of source is defined by trivial computation, try
// rematerializing it.
if (!isExtSubReg && !isInsSubReg && !isSubRegToReg &&
ReMaterializeTrivialDef(SrcInt, DstInt.reg, CopyMI))
ReMaterializeTrivialDef(SrcInt, DstReg, DstSubIdx, CopyMI))
return true;
// If we can eliminate the copy without merging the live ranges, do so now.

View File

@ -206,7 +206,7 @@ namespace llvm {
/// ReMaterializeTrivialDef - If the source of a copy is defined by a trivial
/// computation, replace the copy by rematerialize the definition.
bool ReMaterializeTrivialDef(LiveInterval &SrcInt, unsigned DstReg,
MachineInstr *CopyMI);
unsigned DstSubIdx, MachineInstr *CopyMI);
/// TurnCopyIntoImpDef - If source of the specified copy is an implicit def,
/// turn the copy into an implicit def.

View File

@ -130,9 +130,12 @@ bool TargetInstrInfoImpl::PredicateInstruction(MachineInstr *MI,
void TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned DestReg,
unsigned SubIdx,
const MachineInstr *Orig) const {
MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
MI->getOperand(0).setReg(DestReg);
MachineOperand &MO = MI->getOperand(0);
MO.setReg(DestReg);
MO.setSubReg(SubIdx);
MBB.insert(I, MI);
}

View File

@ -798,6 +798,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
// a = a op c
unsigned regA = mi->getOperand(ti).getReg();
unsigned regB = mi->getOperand(si).getReg();
unsigned regASubIdx = mi->getOperand(ti).getSubReg();
assert(TargetRegisterInfo::isVirtualRegister(regB) &&
"cannot update physical register live information");
@ -946,7 +947,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
DefMI->isSafeToReMat(TII, regB) &&
isProfitableToReMat(regB, rc, mi, DefMI, mbbi, Dist)){
DEBUG(cerr << "2addr: REMATTING : " << *DefMI << "\n");
TII->reMaterialize(*mbbi, mi, regA, DefMI);
TII->reMaterialize(*mbbi, mi, regA, regASubIdx, DefMI);
ReMatRegs.set(regB);
++NumReMats;
} else {

View File

@ -490,7 +490,7 @@ static void ReMaterialize(MachineBasicBlock &MBB,
const TargetInstrInfo *TII,
const TargetRegisterInfo *TRI,
VirtRegMap &VRM) {
TII->reMaterialize(MBB, MII, DestReg, VRM.getReMaterializedMI(Reg));
TII->reMaterialize(MBB, MII, DestReg, 0, VRM.getReMaterializedMI(Reg));
MachineInstr *NewMI = prior(MII);
for (unsigned i = 0, e = NewMI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = NewMI->getOperand(i);

View File

@ -887,7 +887,7 @@ void ARMBaseRegisterInfo::
emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
DebugLoc dl,
unsigned DestReg, int Val,
unsigned DestReg, unsigned SubIdx, int Val,
ARMCC::CondCodes Pred,
unsigned PredReg) const {
MachineFunction &MF = *MBB.getParent();
@ -896,7 +896,8 @@ emitLoadConstPool(MachineBasicBlock &MBB,
MF.getFunction()->getContext()->getConstantInt(Type::Int32Ty, Val);
unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp), DestReg)
BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp))
.addReg(DestReg, getDefRegState(true), SubIdx)
.addConstantPoolIndex(Idx)
.addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
}

View File

@ -112,7 +112,8 @@ public:
virtual void emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
DebugLoc dl,
unsigned DestReg, int Val,
unsigned DestReg, unsigned SubIdx,
int Val,
ARMCC::CondCodes Pred = ARMCC::AL,
unsigned PredReg = 0) const;

View File

@ -117,12 +117,12 @@ BlockHasNoFallThrough(const MachineBasicBlock &MBB) const {
void ARMInstrInfo::
reMaterialize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned DestReg,
unsigned DestReg, unsigned SubIdx,
const MachineInstr *Orig) const {
DebugLoc dl = Orig->getDebugLoc();
if (Orig->getOpcode() == ARM::MOVi2pieces) {
RI.emitLoadConstPool(MBB, I, dl,
DestReg,
DestReg, SubIdx,
Orig->getOperand(1).getImm(),
(ARMCC::CondCodes)Orig->getOperand(2).getImm(),
Orig->getOperand(3).getReg());

View File

@ -45,7 +45,8 @@ public:
const ARMRegisterInfo &getRegisterInfo() const { return RI; }
void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
unsigned DestReg, const MachineInstr *Orig) const;
unsigned DestReg, unsigned SubIdx,
const MachineInstr *Orig) const;
};
}

View File

@ -62,7 +62,8 @@ const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) {
void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
DebugLoc dl,
unsigned DestReg, int Val,
unsigned DestReg, unsigned SubIdx,
int Val,
ARMCC::CondCodes Pred,
unsigned PredReg) const {
MachineFunction &MF = *MBB.getParent();
@ -71,8 +72,9 @@ void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
MF.getFunction()->getContext()->getConstantInt(Type::Int32Ty, Val);
unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRcp), DestReg)
.addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg);
BuildMI(MBB, MBBI, dl, TII.get(ARM::tLDRcp))
.addReg(DestReg, getDefRegState(true), SubIdx)
.addConstantPoolIndex(Idx).addImm(Pred).addReg(PredReg);
}
const TargetRegisterClass*
@ -149,7 +151,7 @@ void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
AddDefaultCC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg))
.addReg(LdReg, RegState::Kill);
} else
MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, NumBytes);
MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes);
// Emit add / sub.
int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
@ -570,7 +572,7 @@ void Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
Offset, false, TII, *this, dl);
else {
emitLoadConstPool(MBB, II, dl, TmpReg, Offset);
emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
UseRR = true;
}
} else {
@ -610,7 +612,7 @@ void Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
Offset, false, TII, *this, dl);
else {
emitLoadConstPool(MBB, II, dl, TmpReg, Offset);
emitLoadConstPool(MBB, II, dl, TmpReg, 0, Offset);
UseRR = true;
}
} else

View File

@ -32,7 +32,7 @@ public:
void emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
DebugLoc dl,
unsigned DestReg, int Val,
unsigned DestReg, unsigned SubIdx, int Val,
ARMCC::CondCodes Pred = ARMCC::AL,
unsigned PredReg = 0) const;

View File

@ -46,7 +46,8 @@ Thumb2RegisterInfo::Thumb2RegisterInfo(const ARMBaseInstrInfo &tii,
void Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
DebugLoc dl,
unsigned DestReg, int Val,
unsigned DestReg, unsigned SubIdx,
int Val,
ARMCC::CondCodes Pred,
unsigned PredReg) const {
MachineFunction &MF = *MBB.getParent();
@ -55,7 +56,8 @@ void Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
MF.getFunction()->getContext()->getConstantInt(Type::Int32Ty, Val);
unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci), DestReg)
BuildMI(MBB, MBBI, dl, TII.get(ARM::t2LDRpci))
.addReg(DestReg, getDefRegState(true), SubIdx)
.addConstantPoolIndex(Idx).addImm((int64_t)ARMCC::AL).addReg(0);
}

View File

@ -32,7 +32,7 @@ public:
void emitLoadConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
DebugLoc dl,
unsigned DestReg, int Val,
unsigned DestReg, unsigned SubIdx, int Val,
ARMCC::CondCodes Pred = ARMCC::AL,
unsigned PredReg = 0) const;

View File

@ -916,14 +916,11 @@ static bool isSafeToClobberEFLAGS(MachineBasicBlock &MBB,
void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned DestReg,
unsigned DestReg, unsigned SubIdx,
const MachineInstr *Orig) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
if (I != MBB.end()) DL = I->getDebugLoc();
unsigned SubIdx = Orig->getOperand(0).isReg()
? Orig->getOperand(0).getSubReg() : 0;
bool ChangeSubIdx = SubIdx != 0;
if (SubIdx && TargetRegisterInfo::isPhysicalRegister(DestReg)) {
DestReg = RI.getSubReg(DestReg, SubIdx);
SubIdx = 0;
@ -931,37 +928,36 @@ void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
// MOV32r0 etc. are implemented with xor which clobbers condition code.
// Re-materialize them as movri instructions to avoid side effects.
bool Emitted = false;
switch (Orig->getOpcode()) {
bool Clone = true;
unsigned Opc = Orig->getOpcode();
switch (Opc) {
default: break;
case X86::MOV8r0:
case X86::MOV16r0:
case X86::MOV32r0: {
if (!isSafeToClobberEFLAGS(MBB, I)) {
unsigned Opc = 0;
switch (Orig->getOpcode()) {
switch (Opc) {
default: break;
case X86::MOV8r0: Opc = X86::MOV8ri; break;
case X86::MOV16r0: Opc = X86::MOV16ri; break;
case X86::MOV32r0: Opc = X86::MOV32ri; break;
}
BuildMI(MBB, I, DL, get(Opc), DestReg).addImm(0);
Emitted = true;
Clone = false;
}
break;
}
}
if (!Emitted) {
if (Clone) {
MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
MI->getOperand(0).setReg(DestReg);
MBB.insert(I, MI);
} else {
BuildMI(MBB, I, DL, get(Opc), DestReg).addImm(0);
}
if (ChangeSubIdx) {
MachineInstr *NewMI = prior(I);
NewMI->getOperand(0).setSubReg(SubIdx);
}
MachineInstr *NewMI = prior(I);
NewMI->getOperand(0).setSubReg(SubIdx);
}
/// isInvariantLoad - Return true if the specified instruction (which is marked

View File

@ -456,7 +456,8 @@ public:
bool isReallyTriviallyReMaterializable(const MachineInstr *MI) const;
void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
unsigned DestReg, const MachineInstr *Orig) const;
unsigned DestReg, unsigned SubIdx,
const MachineInstr *Orig) const;
bool isInvariantLoad(const MachineInstr *MI) const;

View File

@ -1,7 +1,11 @@
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep movd | count 1
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep movq
; PR2677
; FIXME: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep movd | count 1
; We now no longer allow instruction whose def has a sub-reg index to be
; rematerialized.
%struct.Bigint = type { %struct.Bigint*, i32, i32, i32, i32, [1 x i32] }
define double @_Z7qstrtodPKcPS0_Pb(i8* %s00, i8** %se, i8* %ok) nounwind {

View File

@ -0,0 +1,210 @@
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin10
; rdar://7059496
%struct.brinfo = type <{ %struct.brinfo*, %struct.brinfo*, i8*, i32, i32, i32, i8, i8, i8, i8 }>
%struct.cadata = type <{ i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i32, %struct.cmatcher*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i8, i8, i8, i8 }>
%struct.cline = type <{ %struct.cline*, i32, i8, i8, i8, i8, i8*, i32, i8, i8, i8, i8, i8*, i32, i8, i8, i8, i8, i8*, i32, i32, %struct.cline*, %struct.cline*, i32, i32 }>
%struct.cmatch = type <{ i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i8, i8, i8, i8, i32*, i32*, i8*, i8*, i32, i32, i32, i32, i16, i8, i8, i16, i8, i8 }>
%struct.cmatcher = type <{ i32, i8, i8, i8, i8, %struct.cmatcher*, i32, i8, i8, i8, i8, %struct.cpattern*, i32, i8, i8, i8, i8, %struct.cpattern*, i32, i8, i8, i8, i8, %struct.cpattern*, i32, i8, i8, i8, i8, %struct.cpattern*, i32, i8, i8, i8, i8 }>
%struct.cpattern = type <{ %struct.cpattern*, i32, i8, i8, i8, i8, %union.anon }>
%struct.patprog = type <{ i64, i64, i64, i64, i32, i32, i32, i32, i8, i8, i8, i8, i8, i8, i8, i8 }>
%union.anon = type <{ [8 x i8] }>
define i32 @addmatches(%struct.cadata* %dat, i8** nocapture %argv) nounwind ssp {
entry:
br i1 undef, label %if.else, label %if.then91
if.then91: ; preds = %entry
br label %if.end96
if.else: ; preds = %entry
br label %if.end96
if.end96: ; preds = %if.else, %if.then91
br i1 undef, label %lor.lhs.false, label %if.then105
lor.lhs.false: ; preds = %if.end96
br i1 undef, label %if.else139, label %if.then105
if.then105: ; preds = %lor.lhs.false, %if.end96
unreachable
if.else139: ; preds = %lor.lhs.false
br i1 undef, label %land.end, label %land.rhs
land.rhs: ; preds = %if.else139
unreachable
land.end: ; preds = %if.else139
br i1 undef, label %land.lhs.true285, label %if.then315
land.lhs.true285: ; preds = %land.end
br i1 undef, label %if.end324, label %if.then322
if.then315: ; preds = %land.end
unreachable
if.then322: ; preds = %land.lhs.true285
unreachable
if.end324: ; preds = %land.lhs.true285
br i1 undef, label %if.end384, label %if.then358
if.then358: ; preds = %if.end324
unreachable
if.end384: ; preds = %if.end324
br i1 undef, label %if.end394, label %land.lhs.true387
land.lhs.true387: ; preds = %if.end384
unreachable
if.end394: ; preds = %if.end384
br i1 undef, label %if.end498, label %land.lhs.true399
land.lhs.true399: ; preds = %if.end394
br i1 undef, label %if.end498, label %if.then406
if.then406: ; preds = %land.lhs.true399
unreachable
if.end498: ; preds = %land.lhs.true399, %if.end394
br i1 undef, label %if.end514, label %if.then503
if.then503: ; preds = %if.end498
unreachable
if.end514: ; preds = %if.end498
br i1 undef, label %if.end585, label %if.then520
if.then520: ; preds = %if.end514
br i1 undef, label %lor.lhs.false547, label %if.then560
lor.lhs.false547: ; preds = %if.then520
unreachable
if.then560: ; preds = %if.then520
br i1 undef, label %if.end585, label %land.lhs.true566
land.lhs.true566: ; preds = %if.then560
br i1 undef, label %if.end585, label %if.then573
if.then573: ; preds = %land.lhs.true566
unreachable
if.end585: ; preds = %land.lhs.true566, %if.then560, %if.end514
br i1 undef, label %cond.true593, label %cond.false599
cond.true593: ; preds = %if.end585
unreachable
cond.false599: ; preds = %if.end585
br i1 undef, label %if.end647, label %if.then621
if.then621: ; preds = %cond.false599
br i1 undef, label %cond.true624, label %cond.false630
cond.true624: ; preds = %if.then621
br label %if.end647
cond.false630: ; preds = %if.then621
unreachable
if.end647: ; preds = %cond.true624, %cond.false599
br i1 undef, label %if.end723, label %if.then701
if.then701: ; preds = %if.end647
br label %if.end723
if.end723: ; preds = %if.then701, %if.end647
br i1 undef, label %if.else1090, label %if.then729
if.then729: ; preds = %if.end723
br i1 undef, label %if.end887, label %if.then812
if.then812: ; preds = %if.then729
unreachable
if.end887: ; preds = %if.then729
br i1 undef, label %if.end972, label %if.then893
if.then893: ; preds = %if.end887
br i1 undef, label %if.end919, label %if.then903
if.then903: ; preds = %if.then893
unreachable
if.end919: ; preds = %if.then893
br label %if.end972
if.end972: ; preds = %if.end919, %if.end887
%sline.0 = phi %struct.cline* [ undef, %if.end919 ], [ null, %if.end887 ] ; <%struct.cline*> [#uses=5]
%bcs.0 = phi i32 [ undef, %if.end919 ], [ 0, %if.end887 ] ; <i32> [#uses=5]
br i1 undef, label %if.end1146, label %land.lhs.true975
land.lhs.true975: ; preds = %if.end972
br i1 undef, label %if.end1146, label %if.then980
if.then980: ; preds = %land.lhs.true975
br i1 undef, label %cond.false1025, label %cond.false1004
cond.false1004: ; preds = %if.then980
unreachable
cond.false1025: ; preds = %if.then980
br i1 undef, label %if.end1146, label %if.then1071
if.then1071: ; preds = %cond.false1025
br i1 undef, label %if.then1074, label %if.end1081
if.then1074: ; preds = %if.then1071
br label %if.end1081
if.end1081: ; preds = %if.then1074, %if.then1071
%call1083 = call %struct.patprog* @patcompile(i8* undef, i32 0, i8** null) nounwind ssp ; <%struct.patprog*> [#uses=2]
br i1 undef, label %if.end1146, label %if.then1086
if.then1086: ; preds = %if.end1081
br label %if.end1146
if.else1090: ; preds = %if.end723
br i1 undef, label %if.end1146, label %land.lhs.true1093
land.lhs.true1093: ; preds = %if.else1090
br i1 undef, label %if.end1146, label %if.then1098
if.then1098: ; preds = %land.lhs.true1093
unreachable
if.end1146: ; preds = %land.lhs.true1093, %if.else1090, %if.then1086, %if.end1081, %cond.false1025, %land.lhs.true975, %if.end972
%cp.0 = phi %struct.patprog* [ %call1083, %if.then1086 ], [ null, %if.end972 ], [ null, %land.lhs.true975 ], [ null, %cond.false1025 ], [ %call1083, %if.end1081 ], [ null, %if.else1090 ], [ null, %land.lhs.true1093 ] ; <%struct.patprog*> [#uses=1]
%sline.1 = phi %struct.cline* [ %sline.0, %if.then1086 ], [ %sline.0, %if.end972 ], [ %sline.0, %land.lhs.true975 ], [ %sline.0, %cond.false1025 ], [ %sline.0, %if.end1081 ], [ null, %if.else1090 ], [ null, %land.lhs.true1093 ] ; <%struct.cline*> [#uses=1]
%bcs.1 = phi i32 [ %bcs.0, %if.then1086 ], [ %bcs.0, %if.end972 ], [ %bcs.0, %land.lhs.true975 ], [ %bcs.0, %cond.false1025 ], [ %bcs.0, %if.end1081 ], [ 0, %if.else1090 ], [ 0, %land.lhs.true1093 ] ; <i32> [#uses=1]
br i1 undef, label %if.end1307, label %do.body1270
do.body1270: ; preds = %if.end1146
unreachable
if.end1307: ; preds = %if.end1146
br i1 undef, label %if.end1318, label %if.then1312
if.then1312: ; preds = %if.end1307
unreachable
if.end1318: ; preds = %if.end1307
br i1 undef, label %for.cond1330.preheader, label %if.then1323
if.then1323: ; preds = %if.end1318
unreachable
for.cond1330.preheader: ; preds = %if.end1318
%call1587 = call i8* @comp_match(i8* undef, i8* undef, i8* undef, %struct.patprog* %cp.0, %struct.cline** undef, i32 0, %struct.brinfo** undef, i32 0, %struct.brinfo** undef, i32 %bcs.1, i32* undef) nounwind ssp ; <i8*> [#uses=0]
%call1667 = call %struct.cmatch* @add_match_data(i32 0, i8* undef, i8* undef, %struct.cline* undef, i8* undef, i8* null, i8* undef, i8* undef, i8* undef, i8* undef, %struct.cline* null, i8* undef, %struct.cline* %sline.1, i8* undef, i32 undef, i32 undef) ssp ; <%struct.cmatch*> [#uses=0]
unreachable
}
declare %struct.patprog* @patcompile(i8*, i32, i8**) ssp
declare i8* @comp_match(i8*, i8*, i8*, %struct.patprog*, %struct.cline**, i32, %struct.brinfo**, i32, %struct.brinfo**, i32, i32*) ssp
declare %struct.cmatch* @add_match_data(i32, i8*, i8*, %struct.cline*, i8*, i8*, i8*, i8*, i8*, i8*, %struct.cline*, i8*, %struct.cline*, i8*, i32, i32) nounwind ssp