OLD | NEW |
1 //===-- FastISel.cpp - Implementation of the FastISel class ---------------===// | 1 //===-- FastISel.cpp - Implementation of the FastISel class ---------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file contains the implementation of the FastISel class. | 10 // This file contains the implementation of the FastISel class. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 #include "llvm/Support/ErrorHandling.h" | 59 #include "llvm/Support/ErrorHandling.h" |
60 #include "llvm/Support/Debug.h" | 60 #include "llvm/Support/Debug.h" |
61 using namespace llvm; | 61 using namespace llvm; |
62 | 62 |
63 /// startNewBlock - Set the current block to which generated machine | 63 /// startNewBlock - Set the current block to which generated machine |
64 /// instructions will be appended, and clear the local CSE map. | 64 /// instructions will be appended, and clear the local CSE map. |
65 /// | 65 /// |
66 void FastISel::startNewBlock() { | 66 void FastISel::startNewBlock() { |
67 LocalValueMap.clear(); | 67 LocalValueMap.clear(); |
68 | 68 |
69 // Start out as null, meaining no local-value instructions have | 69 EmitStartPt = 0; |
70 // been emitted. | |
71 LastLocalValue = 0; | |
72 | 70 |
73 // Advance the last local value past any EH_LABEL instructions. | 71 // Advance the emit start point past any EH_LABEL instructions. |
74 MachineBasicBlock::iterator | 72 MachineBasicBlock::iterator |
75 I = FuncInfo.MBB->begin(), E = FuncInfo.MBB->end(); | 73 I = FuncInfo.MBB->begin(), E = FuncInfo.MBB->end(); |
76 while (I != E && I->getOpcode() == TargetOpcode::EH_LABEL) { | 74 while (I != E && I->getOpcode() == TargetOpcode::EH_LABEL) { |
77 LastLocalValue = I; | 75 EmitStartPt = I; |
78 ++I; | 76 ++I; |
79 } | 77 } |
| 78 LastLocalValue = EmitStartPt; |
| 79 } |
| 80 |
| 81 void FastISel::flushLocalValueMap() { |
| 82 LocalValueMap.clear(); |
| 83 LastLocalValue = EmitStartPt; |
| 84 recomputeInsertPt(); |
80 } | 85 } |
81 | 86 |
82 bool FastISel::hasTrivialKill(const Value *V) const { | 87 bool FastISel::hasTrivialKill(const Value *V) const { |
83 // Don't consider constants or arguments to have trivial kills. | 88 // Don't consider constants or arguments to have trivial kills. |
84 const Instruction *I = dyn_cast<Instruction>(V); | 89 const Instruction *I = dyn_cast<Instruction>(V); |
85 if (!I) | 90 if (!I) |
86 return false; | 91 return false; |
87 | 92 |
88 // No-op casts are trivially coalesced by fast-isel. | 93 // No-op casts are trivially coalesced by fast-isel. |
89 if (const CastInst *Cast = dyn_cast<CastInst>(I)) | 94 if (const CastInst *Cast = dyn_cast<CastInst>(I)) |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 unsigned long long Res = CI->isZero() ? -1ULL : 0; | 643 unsigned long long Res = CI->isZero() ? -1ULL : 0; |
639 Constant *ResCI = ConstantInt::get(Call->getType(), Res); | 644 Constant *ResCI = ConstantInt::get(Call->getType(), Res); |
640 unsigned ResultReg = getRegForValue(ResCI); | 645 unsigned ResultReg = getRegForValue(ResCI); |
641 if (ResultReg == 0) | 646 if (ResultReg == 0) |
642 return false; | 647 return false; |
643 UpdateValueMap(Call, ResultReg); | 648 UpdateValueMap(Call, ResultReg); |
644 return true; | 649 return true; |
645 } | 650 } |
646 } | 651 } |
647 | 652 |
| 653 // Usually, it does not make sense to initialize a value, |
| 654 // make an unrelated function call and use the value, because |
| 655 // it tends to be spilled on the stack. So, we move the pointer |
| 656 // to the last local value to the beginning of the block, so that |
| 657 // all the values which have already been materialized, |
| 658 // appear after the call. It also makes sense to skip intrinsics |
| 659 // since they tend to be inlined. |
| 660 if (!isa<IntrinsicInst>(F)) |
| 661 flushLocalValueMap(); |
| 662 |
648 // An arbitrary call. Bail. | 663 // An arbitrary call. Bail. |
649 return false; | 664 return false; |
650 } | 665 } |
651 | 666 |
652 bool FastISel::SelectCast(const User *I, unsigned Opcode) { | 667 bool FastISel::SelectCast(const User *I, unsigned Opcode) { |
653 EVT SrcVT = TLI.getValueType(I->getOperand(0)->getType()); | 668 EVT SrcVT = TLI.getValueType(I->getOperand(0)->getType()); |
654 EVT DstVT = TLI.getValueType(I->getType()); | 669 EVT DstVT = TLI.getValueType(I->getType()); |
655 | 670 |
656 if (SrcVT == MVT::Other || !SrcVT.isSimple() || | 671 if (SrcVT == MVT::Other || !SrcVT.isSimple() || |
657 DstVT == MVT::Other || !DstVT.isSimple()) | 672 DstVT == MVT::Other || !DstVT.isSimple()) |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 FuncInfo.PHINodesToUpdate.resize(OrigNumPHINodesToUpdate); | 1379 FuncInfo.PHINodesToUpdate.resize(OrigNumPHINodesToUpdate); |
1365 return false; | 1380 return false; |
1366 } | 1381 } |
1367 FuncInfo.PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg)); | 1382 FuncInfo.PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg)); |
1368 DL = DebugLoc(); | 1383 DL = DebugLoc(); |
1369 } | 1384 } |
1370 } | 1385 } |
1371 | 1386 |
1372 return true; | 1387 return true; |
1373 } | 1388 } |
OLD | NEW |