llvm.org GIT mirror llvm / 9ef4ca2
If it's determined safe, remat MOV32r0 (i.e. xor r, r) and others as it is instead of using the longer MOV32ri instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52670 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 11 years ago
2 changed file(s) with 100 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
831831 return true;
832832 }
833833
834 /// isSafeToClobberEFLAGS - Return true if it's safe insert an instruction that
835 /// would clobber the EFLAGS condition register. Note the result may be
836 /// conservative. If it cannot definitely determine the safety after visiting
837 /// two instructions it assumes it's not safe.
838 static bool isSafeToClobberEFLAGS(MachineBasicBlock &MBB,
839 MachineBasicBlock::iterator I) {
840 // For compile time consideration, if we are not able to determine the
841 // safety after visiting 2 instructions, we will assume it's not safe.
842 for (unsigned i = 0; i < 2; ++i) {
843 if (I == MBB.end())
844 // Reached end of block, it's safe.
845 return true;
846 bool SeenDef = false;
847 for (unsigned j = 0, e = I->getNumOperands(); j != e; ++j) {
848 MachineOperand &MO = I->getOperand(j);
849 if (!MO.isRegister())
850 continue;
851 if (MO.getReg() == X86::EFLAGS) {
852 if (MO.isUse())
853 return false;
854 SeenDef = true;
855 }
856 }
857
858 if (SeenDef)
859 // This instruction defines EFLAGS, no need to look any further.
860 return true;
861 ++I;
862 }
863
864 // Conservative answer.
865 return false;
866 }
867
834868 void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
835869 MachineBasicBlock::iterator I,
836870 unsigned DestReg,
845879
846880 // MOV32r0 etc. are implemented with xor which clobbers condition code.
847881 // Re-materialize them as movri instructions to avoid side effects.
882 bool Emitted = false;
848883 switch (Orig->getOpcode()) {
884 default: break;
849885 case X86::MOV8r0:
850 BuildMI(MBB, I, get(X86::MOV8ri), DestReg).addImm(0);
886 case X86::MOV16r0:
887 case X86::MOV32r0:
888 case X86::MOV64r0: {
889 if (!isSafeToClobberEFLAGS(MBB, I)) {
890 unsigned Opc = 0;
891 switch (Orig->getOpcode()) {
892 default: break;
893 case X86::MOV8r0: Opc = X86::MOV8ri; break;
894 case X86::MOV16r0: Opc = X86::MOV16ri; break;
895 case X86::MOV32r0: Opc = X86::MOV32ri; break;
896 case X86::MOV64r0: Opc = X86::MOV64ri32; break;
897 }
898 BuildMI(MBB, I, get(Opc), DestReg).addImm(0);
899 Emitted = true;
900 }
851901 break;
852 case X86::MOV16r0:
853 BuildMI(MBB, I, get(X86::MOV16ri), DestReg).addImm(0);
854 break;
855 case X86::MOV32r0:
856 BuildMI(MBB, I, get(X86::MOV32ri), DestReg).addImm(0);
857 break;
858 case X86::MOV64r0:
859 BuildMI(MBB, I, get(X86::MOV64ri32), DestReg).addImm(0);
860 break;
861 default: {
902 }
903 }
904
905 if (!Emitted) {
862906 MachineInstr *MI = Orig->clone();
863907 MI->getOperand(0).setReg(DestReg);
864908 MBB.insert(I, MI);
865 break;
866 }
867909 }
868910
869911 if (ChangeSubIdx) {
0 ; RUN: llvm-as < %s | llc -march=x86 | grep xor | count 3
1
2 %struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
3 %struct.ImgT = type { i8, i8*, i8*, %struct.FILE*, i32, i32, i32, i32, i8*, double*, float*, float*, float*, i32*, double, double, i32*, double*, i32*, i32* }
4 %struct._CompT = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, float, float, i8, %struct._PixT*, %struct._CompT*, i8, %struct._CompT* }
5 %struct._PixT = type { i32, i32, %struct._PixT* }
6 %struct.__sFILEX = type opaque
7 %struct.__sbuf = type { i8*, i32 }
8
9 declare fastcc void @MergeComponents(%struct._CompT*, %struct._CompT*, %struct._CompT*, %struct._CompT**, %struct.ImgT*) nounwind
10
11 define fastcc void @MergeToLeft(%struct._CompT* %comp, %struct._CompT** %head, %struct.ImgT* %img) nounwind {
12 entry:
13 br label %bb208
14
15 bb105: ; preds = %bb200
16 br i1 false, label %bb197, label %bb149
17
18 bb149: ; preds = %bb105
19 %tmp151 = getelementptr %struct._CompT* null, i32 0, i32 0 ; [#uses=1]
20 br i1 false, label %bb184, label %bb193
21
22 bb184: ; preds = %bb149
23 tail call fastcc void @MergeComponents( %struct._CompT* %comp, %struct._CompT* null, %struct._CompT* null, %struct._CompT** %head, %struct.ImgT* %img ) nounwind
24 tail call fastcc void @MergeToLeft( %struct._CompT* %comp, %struct._CompT** %head, %struct.ImgT* %img ) nounwind
25 br label %bb193
26
27 bb193: ; preds = %bb184, %bb149
28 %tmp196 = load i32* %tmp151, align 4 ; [#uses=1]
29 br label %bb197
30
31 bb197: ; preds = %bb193, %bb105
32 %last_comp.0 = phi i32 [ %tmp196, %bb193 ], [ 0, %bb105 ] ; [#uses=0]
33 %indvar.next = add i32 %indvar, 1 ; [#uses=1]
34 br label %bb200
35
36 bb200: ; preds = %bb208, %bb197
37 %indvar = phi i32 [ 0, %bb208 ], [ %indvar.next, %bb197 ] ; [#uses=2]
38 %xm.0 = sub i32 %indvar, 0 ; [#uses=1]
39 %tmp202 = icmp slt i32 %xm.0, 1 ; [#uses=1]
40 br i1 %tmp202, label %bb105, label %bb208
41
42 bb208: ; preds = %bb200, %entry
43 br label %bb200
44 }