| Chris Lattner | 310968c | 2005-01-07 07:44:53 +0000 | [diff] [blame] | 1 | //===-- TargetLowering.cpp - Implement the TargetLowering class -----------===// | 
| Misha Brukman | f976c85 | 2005-04-21 22:55:34 +0000 | [diff] [blame] | 2 | // | 
| Chris Lattner | 310968c | 2005-01-07 07:44:53 +0000 | [diff] [blame] | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
| Chris Lattner | 4ee451d | 2007-12-29 20:36:04 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
| Misha Brukman | f976c85 | 2005-04-21 22:55:34 +0000 | [diff] [blame] | 7 | // | 
| Chris Lattner | 310968c | 2005-01-07 07:44:53 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
 | 10 | // This implements the TargetLowering class. | 
 | 11 | // | 
 | 12 | //===----------------------------------------------------------------------===// | 
 | 13 |  | 
 | 14 | #include "llvm/Target/TargetLowering.h" | 
| Chris Lattner | f014412 | 2009-07-28 03:13:23 +0000 | [diff] [blame] | 15 | #include "llvm/Target/TargetAsmInfo.h" | 
| Owen Anderson | 07000c6 | 2006-05-12 06:33:49 +0000 | [diff] [blame] | 16 | #include "llvm/Target/TargetData.h" | 
| Chris Lattner | f014412 | 2009-07-28 03:13:23 +0000 | [diff] [blame] | 17 | #include "llvm/Target/TargetLoweringObjectFile.h" | 
| Chris Lattner | 310968c | 2005-01-07 07:44:53 +0000 | [diff] [blame] | 18 | #include "llvm/Target/TargetMachine.h" | 
| Dan Gohman | 6f0d024 | 2008-02-10 18:45:23 +0000 | [diff] [blame] | 19 | #include "llvm/Target/TargetRegisterInfo.h" | 
| Chris Lattner | f014412 | 2009-07-28 03:13:23 +0000 | [diff] [blame] | 20 | #include "llvm/Target/TargetSubtarget.h" | 
| Dan Gohman | 707e018 | 2008-04-12 04:36:06 +0000 | [diff] [blame] | 21 | #include "llvm/GlobalVariable.h" | 
| Chris Lattner | dc87929 | 2006-03-31 00:28:56 +0000 | [diff] [blame] | 22 | #include "llvm/DerivedTypes.h" | 
| Evan Cheng | ad4196b | 2008-05-12 19:56:52 +0000 | [diff] [blame] | 23 | #include "llvm/CodeGen/MachineFrameInfo.h" | 
| Chris Lattner | 310968c | 2005-01-07 07:44:53 +0000 | [diff] [blame] | 24 | #include "llvm/CodeGen/SelectionDAG.h" | 
| Chris Lattner | 4ccb070 | 2006-01-26 20:37:03 +0000 | [diff] [blame] | 25 | #include "llvm/ADT/StringExtras.h" | 
| Owen Anderson | 718cb66 | 2007-09-07 04:06:50 +0000 | [diff] [blame] | 26 | #include "llvm/ADT/STLExtras.h" | 
| Torok Edwin | c25e758 | 2009-07-11 20:10:48 +0000 | [diff] [blame] | 27 | #include "llvm/Support/ErrorHandling.h" | 
| Chris Lattner | c6fd6cd | 2006-01-30 04:09:27 +0000 | [diff] [blame] | 28 | #include "llvm/Support/MathExtras.h" | 
| Chris Lattner | 310968c | 2005-01-07 07:44:53 +0000 | [diff] [blame] | 29 | using namespace llvm; | 
 | 30 |  | 
| Rafael Espindola | 9a58023 | 2009-02-27 13:37:18 +0000 | [diff] [blame] | 31 | namespace llvm { | 
 | 32 | TLSModel::Model getTLSModel(const GlobalValue *GV, Reloc::Model reloc) { | 
 | 33 |   bool isLocal = GV->hasLocalLinkage(); | 
 | 34 |   bool isDeclaration = GV->isDeclaration(); | 
 | 35 |   // FIXME: what should we do for protected and internal visibility? | 
 | 36 |   // For variables, is internal different from hidden? | 
 | 37 |   bool isHidden = GV->hasHiddenVisibility(); | 
 | 38 |  | 
 | 39 |   if (reloc == Reloc::PIC_) { | 
 | 40 |     if (isLocal || isHidden) | 
 | 41 |       return TLSModel::LocalDynamic; | 
 | 42 |     else | 
 | 43 |       return TLSModel::GeneralDynamic; | 
 | 44 |   } else { | 
 | 45 |     if (!isDeclaration || isHidden) | 
 | 46 |       return TLSModel::LocalExec; | 
 | 47 |     else | 
 | 48 |       return TLSModel::InitialExec; | 
 | 49 |   } | 
 | 50 | } | 
 | 51 | } | 
 | 52 |  | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 53 | /// InitLibcallNames - Set default libcall names. | 
 | 54 | /// | 
| Evan Cheng | 79cca50 | 2007-01-12 22:51:10 +0000 | [diff] [blame] | 55 | static void InitLibcallNames(const char **Names) { | 
| Anton Korobeynikov | c31642f | 2009-05-03 13:14:08 +0000 | [diff] [blame] | 56 |   Names[RTLIB::SHL_I16] = "__ashlhi3"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 57 |   Names[RTLIB::SHL_I32] = "__ashlsi3"; | 
 | 58 |   Names[RTLIB::SHL_I64] = "__ashldi3"; | 
| Duncan Sands | dddc629 | 2008-07-11 16:52:29 +0000 | [diff] [blame] | 59 |   Names[RTLIB::SHL_I128] = "__ashlti3"; | 
| Anton Korobeynikov | c31642f | 2009-05-03 13:14:08 +0000 | [diff] [blame] | 60 |   Names[RTLIB::SRL_I16] = "__lshrhi3"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 61 |   Names[RTLIB::SRL_I32] = "__lshrsi3"; | 
 | 62 |   Names[RTLIB::SRL_I64] = "__lshrdi3"; | 
| Duncan Sands | dddc629 | 2008-07-11 16:52:29 +0000 | [diff] [blame] | 63 |   Names[RTLIB::SRL_I128] = "__lshrti3"; | 
| Anton Korobeynikov | c31642f | 2009-05-03 13:14:08 +0000 | [diff] [blame] | 64 |   Names[RTLIB::SRA_I16] = "__ashrhi3"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 65 |   Names[RTLIB::SRA_I32] = "__ashrsi3"; | 
 | 66 |   Names[RTLIB::SRA_I64] = "__ashrdi3"; | 
| Duncan Sands | dddc629 | 2008-07-11 16:52:29 +0000 | [diff] [blame] | 67 |   Names[RTLIB::SRA_I128] = "__ashrti3"; | 
| Anton Korobeynikov | c31642f | 2009-05-03 13:14:08 +0000 | [diff] [blame] | 68 |   Names[RTLIB::MUL_I16] = "__mulhi3"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 69 |   Names[RTLIB::MUL_I32] = "__mulsi3"; | 
 | 70 |   Names[RTLIB::MUL_I64] = "__muldi3"; | 
| Duncan Sands | 5ac319a | 2008-07-10 15:35:05 +0000 | [diff] [blame] | 71 |   Names[RTLIB::MUL_I128] = "__multi3"; | 
| Anton Korobeynikov | 813090c | 2009-05-03 13:18:16 +0000 | [diff] [blame] | 72 |   Names[RTLIB::SDIV_I16] = "__divhi3"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 73 |   Names[RTLIB::SDIV_I32] = "__divsi3"; | 
 | 74 |   Names[RTLIB::SDIV_I64] = "__divdi3"; | 
| Duncan Sands | 5ac319a | 2008-07-10 15:35:05 +0000 | [diff] [blame] | 75 |   Names[RTLIB::SDIV_I128] = "__divti3"; | 
| Anton Korobeynikov | fb3f84f | 2009-05-08 18:50:54 +0000 | [diff] [blame] | 76 |   Names[RTLIB::UDIV_I16] = "__udivhi3"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 77 |   Names[RTLIB::UDIV_I32] = "__udivsi3"; | 
 | 78 |   Names[RTLIB::UDIV_I64] = "__udivdi3"; | 
| Duncan Sands | 5ac319a | 2008-07-10 15:35:05 +0000 | [diff] [blame] | 79 |   Names[RTLIB::UDIV_I128] = "__udivti3"; | 
| Anton Korobeynikov | 813090c | 2009-05-03 13:18:16 +0000 | [diff] [blame] | 80 |   Names[RTLIB::SREM_I16] = "__modhi3"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 81 |   Names[RTLIB::SREM_I32] = "__modsi3"; | 
 | 82 |   Names[RTLIB::SREM_I64] = "__moddi3"; | 
| Duncan Sands | 5ac319a | 2008-07-10 15:35:05 +0000 | [diff] [blame] | 83 |   Names[RTLIB::SREM_I128] = "__modti3"; | 
| Anton Korobeynikov | 9fe9c8e | 2009-05-03 13:19:57 +0000 | [diff] [blame] | 84 |   Names[RTLIB::UREM_I16] = "__umodhi3"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 85 |   Names[RTLIB::UREM_I32] = "__umodsi3"; | 
 | 86 |   Names[RTLIB::UREM_I64] = "__umoddi3"; | 
| Duncan Sands | 5ac319a | 2008-07-10 15:35:05 +0000 | [diff] [blame] | 87 |   Names[RTLIB::UREM_I128] = "__umodti3"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 88 |   Names[RTLIB::NEG_I32] = "__negsi2"; | 
 | 89 |   Names[RTLIB::NEG_I64] = "__negdi2"; | 
 | 90 |   Names[RTLIB::ADD_F32] = "__addsf3"; | 
 | 91 |   Names[RTLIB::ADD_F64] = "__adddf3"; | 
| Duncan Sands | 007f984 | 2008-01-10 10:28:30 +0000 | [diff] [blame] | 92 |   Names[RTLIB::ADD_F80] = "__addxf3"; | 
| Dale Johannesen | 161e897 | 2007-10-05 20:04:43 +0000 | [diff] [blame] | 93 |   Names[RTLIB::ADD_PPCF128] = "__gcc_qadd"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 94 |   Names[RTLIB::SUB_F32] = "__subsf3"; | 
 | 95 |   Names[RTLIB::SUB_F64] = "__subdf3"; | 
| Duncan Sands | 007f984 | 2008-01-10 10:28:30 +0000 | [diff] [blame] | 96 |   Names[RTLIB::SUB_F80] = "__subxf3"; | 
| Dale Johannesen | 161e897 | 2007-10-05 20:04:43 +0000 | [diff] [blame] | 97 |   Names[RTLIB::SUB_PPCF128] = "__gcc_qsub"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 98 |   Names[RTLIB::MUL_F32] = "__mulsf3"; | 
 | 99 |   Names[RTLIB::MUL_F64] = "__muldf3"; | 
| Duncan Sands | 007f984 | 2008-01-10 10:28:30 +0000 | [diff] [blame] | 100 |   Names[RTLIB::MUL_F80] = "__mulxf3"; | 
| Dale Johannesen | 161e897 | 2007-10-05 20:04:43 +0000 | [diff] [blame] | 101 |   Names[RTLIB::MUL_PPCF128] = "__gcc_qmul"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 102 |   Names[RTLIB::DIV_F32] = "__divsf3"; | 
 | 103 |   Names[RTLIB::DIV_F64] = "__divdf3"; | 
| Duncan Sands | 007f984 | 2008-01-10 10:28:30 +0000 | [diff] [blame] | 104 |   Names[RTLIB::DIV_F80] = "__divxf3"; | 
| Dale Johannesen | 161e897 | 2007-10-05 20:04:43 +0000 | [diff] [blame] | 105 |   Names[RTLIB::DIV_PPCF128] = "__gcc_qdiv"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 106 |   Names[RTLIB::REM_F32] = "fmodf"; | 
 | 107 |   Names[RTLIB::REM_F64] = "fmod"; | 
| Duncan Sands | 007f984 | 2008-01-10 10:28:30 +0000 | [diff] [blame] | 108 |   Names[RTLIB::REM_F80] = "fmodl"; | 
| Dale Johannesen | 161e897 | 2007-10-05 20:04:43 +0000 | [diff] [blame] | 109 |   Names[RTLIB::REM_PPCF128] = "fmodl"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 110 |   Names[RTLIB::POWI_F32] = "__powisf2"; | 
 | 111 |   Names[RTLIB::POWI_F64] = "__powidf2"; | 
| Dale Johannesen | 161e897 | 2007-10-05 20:04:43 +0000 | [diff] [blame] | 112 |   Names[RTLIB::POWI_F80] = "__powixf2"; | 
 | 113 |   Names[RTLIB::POWI_PPCF128] = "__powitf2"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 114 |   Names[RTLIB::SQRT_F32] = "sqrtf"; | 
 | 115 |   Names[RTLIB::SQRT_F64] = "sqrt"; | 
| Dale Johannesen | 161e897 | 2007-10-05 20:04:43 +0000 | [diff] [blame] | 116 |   Names[RTLIB::SQRT_F80] = "sqrtl"; | 
 | 117 |   Names[RTLIB::SQRT_PPCF128] = "sqrtl"; | 
| Dale Johannesen | 7794f2a | 2008-09-04 00:47:13 +0000 | [diff] [blame] | 118 |   Names[RTLIB::LOG_F32] = "logf"; | 
 | 119 |   Names[RTLIB::LOG_F64] = "log"; | 
 | 120 |   Names[RTLIB::LOG_F80] = "logl"; | 
 | 121 |   Names[RTLIB::LOG_PPCF128] = "logl"; | 
 | 122 |   Names[RTLIB::LOG2_F32] = "log2f"; | 
 | 123 |   Names[RTLIB::LOG2_F64] = "log2"; | 
 | 124 |   Names[RTLIB::LOG2_F80] = "log2l"; | 
 | 125 |   Names[RTLIB::LOG2_PPCF128] = "log2l"; | 
 | 126 |   Names[RTLIB::LOG10_F32] = "log10f"; | 
 | 127 |   Names[RTLIB::LOG10_F64] = "log10"; | 
 | 128 |   Names[RTLIB::LOG10_F80] = "log10l"; | 
 | 129 |   Names[RTLIB::LOG10_PPCF128] = "log10l"; | 
 | 130 |   Names[RTLIB::EXP_F32] = "expf"; | 
 | 131 |   Names[RTLIB::EXP_F64] = "exp"; | 
 | 132 |   Names[RTLIB::EXP_F80] = "expl"; | 
 | 133 |   Names[RTLIB::EXP_PPCF128] = "expl"; | 
 | 134 |   Names[RTLIB::EXP2_F32] = "exp2f"; | 
 | 135 |   Names[RTLIB::EXP2_F64] = "exp2"; | 
 | 136 |   Names[RTLIB::EXP2_F80] = "exp2l"; | 
 | 137 |   Names[RTLIB::EXP2_PPCF128] = "exp2l"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 138 |   Names[RTLIB::SIN_F32] = "sinf"; | 
 | 139 |   Names[RTLIB::SIN_F64] = "sin"; | 
| Duncan Sands | 007f984 | 2008-01-10 10:28:30 +0000 | [diff] [blame] | 140 |   Names[RTLIB::SIN_F80] = "sinl"; | 
 | 141 |   Names[RTLIB::SIN_PPCF128] = "sinl"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 142 |   Names[RTLIB::COS_F32] = "cosf"; | 
 | 143 |   Names[RTLIB::COS_F64] = "cos"; | 
| Duncan Sands | 007f984 | 2008-01-10 10:28:30 +0000 | [diff] [blame] | 144 |   Names[RTLIB::COS_F80] = "cosl"; | 
 | 145 |   Names[RTLIB::COS_PPCF128] = "cosl"; | 
| Dan Gohman | e54be10 | 2007-10-11 23:09:10 +0000 | [diff] [blame] | 146 |   Names[RTLIB::POW_F32] = "powf"; | 
 | 147 |   Names[RTLIB::POW_F64] = "pow"; | 
 | 148 |   Names[RTLIB::POW_F80] = "powl"; | 
 | 149 |   Names[RTLIB::POW_PPCF128] = "powl"; | 
| Dan Gohman | 2bb1e3e | 2008-08-21 18:38:14 +0000 | [diff] [blame] | 150 |   Names[RTLIB::CEIL_F32] = "ceilf"; | 
 | 151 |   Names[RTLIB::CEIL_F64] = "ceil"; | 
 | 152 |   Names[RTLIB::CEIL_F80] = "ceill"; | 
 | 153 |   Names[RTLIB::CEIL_PPCF128] = "ceill"; | 
 | 154 |   Names[RTLIB::TRUNC_F32] = "truncf"; | 
 | 155 |   Names[RTLIB::TRUNC_F64] = "trunc"; | 
 | 156 |   Names[RTLIB::TRUNC_F80] = "truncl"; | 
 | 157 |   Names[RTLIB::TRUNC_PPCF128] = "truncl"; | 
 | 158 |   Names[RTLIB::RINT_F32] = "rintf"; | 
 | 159 |   Names[RTLIB::RINT_F64] = "rint"; | 
 | 160 |   Names[RTLIB::RINT_F80] = "rintl"; | 
 | 161 |   Names[RTLIB::RINT_PPCF128] = "rintl"; | 
 | 162 |   Names[RTLIB::NEARBYINT_F32] = "nearbyintf"; | 
 | 163 |   Names[RTLIB::NEARBYINT_F64] = "nearbyint"; | 
 | 164 |   Names[RTLIB::NEARBYINT_F80] = "nearbyintl"; | 
 | 165 |   Names[RTLIB::NEARBYINT_PPCF128] = "nearbyintl"; | 
 | 166 |   Names[RTLIB::FLOOR_F32] = "floorf"; | 
 | 167 |   Names[RTLIB::FLOOR_F64] = "floor"; | 
 | 168 |   Names[RTLIB::FLOOR_F80] = "floorl"; | 
 | 169 |   Names[RTLIB::FLOOR_PPCF128] = "floorl"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 170 |   Names[RTLIB::FPEXT_F32_F64] = "__extendsfdf2"; | 
 | 171 |   Names[RTLIB::FPROUND_F64_F32] = "__truncdfsf2"; | 
| Bruno Cardoso Lopes | e36bfe6 | 2008-08-07 19:01:24 +0000 | [diff] [blame] | 172 |   Names[RTLIB::FPROUND_F80_F32] = "__truncxfsf2"; | 
 | 173 |   Names[RTLIB::FPROUND_PPCF128_F32] = "__trunctfsf2"; | 
 | 174 |   Names[RTLIB::FPROUND_F80_F64] = "__truncxfdf2"; | 
 | 175 |   Names[RTLIB::FPROUND_PPCF128_F64] = "__trunctfdf2"; | 
| Sanjiv Gupta | 7d8d36a | 2009-06-16 10:22:58 +0000 | [diff] [blame] | 176 |   Names[RTLIB::FPTOSINT_F32_I8] = "__fixsfi8"; | 
 | 177 |   Names[RTLIB::FPTOSINT_F32_I16] = "__fixsfi16"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 178 |   Names[RTLIB::FPTOSINT_F32_I32] = "__fixsfsi"; | 
 | 179 |   Names[RTLIB::FPTOSINT_F32_I64] = "__fixsfdi"; | 
| Dan Gohman | a2e9485 | 2008-03-10 23:03:31 +0000 | [diff] [blame] | 180 |   Names[RTLIB::FPTOSINT_F32_I128] = "__fixsfti"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 181 |   Names[RTLIB::FPTOSINT_F64_I32] = "__fixdfsi"; | 
 | 182 |   Names[RTLIB::FPTOSINT_F64_I64] = "__fixdfdi"; | 
| Dan Gohman | a2e9485 | 2008-03-10 23:03:31 +0000 | [diff] [blame] | 183 |   Names[RTLIB::FPTOSINT_F64_I128] = "__fixdfti"; | 
| Duncan Sands | be1ad4d | 2008-07-10 15:33:02 +0000 | [diff] [blame] | 184 |   Names[RTLIB::FPTOSINT_F80_I32] = "__fixxfsi"; | 
| Dale Johannesen | 161e897 | 2007-10-05 20:04:43 +0000 | [diff] [blame] | 185 |   Names[RTLIB::FPTOSINT_F80_I64] = "__fixxfdi"; | 
| Dan Gohman | a2e9485 | 2008-03-10 23:03:31 +0000 | [diff] [blame] | 186 |   Names[RTLIB::FPTOSINT_F80_I128] = "__fixxfti"; | 
| Duncan Sands | 041cde2 | 2008-06-25 20:24:48 +0000 | [diff] [blame] | 187 |   Names[RTLIB::FPTOSINT_PPCF128_I32] = "__fixtfsi"; | 
| Dale Johannesen | 161e897 | 2007-10-05 20:04:43 +0000 | [diff] [blame] | 188 |   Names[RTLIB::FPTOSINT_PPCF128_I64] = "__fixtfdi"; | 
| Dan Gohman | a2e9485 | 2008-03-10 23:03:31 +0000 | [diff] [blame] | 189 |   Names[RTLIB::FPTOSINT_PPCF128_I128] = "__fixtfti"; | 
| Sanjiv Gupta | 7d8d36a | 2009-06-16 10:22:58 +0000 | [diff] [blame] | 190 |   Names[RTLIB::FPTOUINT_F32_I8] = "__fixunssfi8"; | 
 | 191 |   Names[RTLIB::FPTOUINT_F32_I16] = "__fixunssfi16"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 192 |   Names[RTLIB::FPTOUINT_F32_I32] = "__fixunssfsi"; | 
 | 193 |   Names[RTLIB::FPTOUINT_F32_I64] = "__fixunssfdi"; | 
| Dan Gohman | a2e9485 | 2008-03-10 23:03:31 +0000 | [diff] [blame] | 194 |   Names[RTLIB::FPTOUINT_F32_I128] = "__fixunssfti"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 195 |   Names[RTLIB::FPTOUINT_F64_I32] = "__fixunsdfsi"; | 
 | 196 |   Names[RTLIB::FPTOUINT_F64_I64] = "__fixunsdfdi"; | 
| Dan Gohman | a2e9485 | 2008-03-10 23:03:31 +0000 | [diff] [blame] | 197 |   Names[RTLIB::FPTOUINT_F64_I128] = "__fixunsdfti"; | 
| Dale Johannesen | 161e897 | 2007-10-05 20:04:43 +0000 | [diff] [blame] | 198 |   Names[RTLIB::FPTOUINT_F80_I32] = "__fixunsxfsi"; | 
 | 199 |   Names[RTLIB::FPTOUINT_F80_I64] = "__fixunsxfdi"; | 
| Dan Gohman | a2e9485 | 2008-03-10 23:03:31 +0000 | [diff] [blame] | 200 |   Names[RTLIB::FPTOUINT_F80_I128] = "__fixunsxfti"; | 
| Duncan Sands | 041cde2 | 2008-06-25 20:24:48 +0000 | [diff] [blame] | 201 |   Names[RTLIB::FPTOUINT_PPCF128_I32] = "__fixunstfsi"; | 
| Dale Johannesen | 161e897 | 2007-10-05 20:04:43 +0000 | [diff] [blame] | 202 |   Names[RTLIB::FPTOUINT_PPCF128_I64] = "__fixunstfdi"; | 
| Dan Gohman | a2e9485 | 2008-03-10 23:03:31 +0000 | [diff] [blame] | 203 |   Names[RTLIB::FPTOUINT_PPCF128_I128] = "__fixunstfti"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 204 |   Names[RTLIB::SINTTOFP_I32_F32] = "__floatsisf"; | 
 | 205 |   Names[RTLIB::SINTTOFP_I32_F64] = "__floatsidf"; | 
| Duncan Sands | 9bed0f5 | 2008-07-11 16:57:02 +0000 | [diff] [blame] | 206 |   Names[RTLIB::SINTTOFP_I32_F80] = "__floatsixf"; | 
 | 207 |   Names[RTLIB::SINTTOFP_I32_PPCF128] = "__floatsitf"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 208 |   Names[RTLIB::SINTTOFP_I64_F32] = "__floatdisf"; | 
 | 209 |   Names[RTLIB::SINTTOFP_I64_F64] = "__floatdidf"; | 
| Dale Johannesen | 161e897 | 2007-10-05 20:04:43 +0000 | [diff] [blame] | 210 |   Names[RTLIB::SINTTOFP_I64_F80] = "__floatdixf"; | 
 | 211 |   Names[RTLIB::SINTTOFP_I64_PPCF128] = "__floatditf"; | 
| Dan Gohman | d91446d | 2008-03-05 01:08:17 +0000 | [diff] [blame] | 212 |   Names[RTLIB::SINTTOFP_I128_F32] = "__floattisf"; | 
 | 213 |   Names[RTLIB::SINTTOFP_I128_F64] = "__floattidf"; | 
 | 214 |   Names[RTLIB::SINTTOFP_I128_F80] = "__floattixf"; | 
 | 215 |   Names[RTLIB::SINTTOFP_I128_PPCF128] = "__floattitf"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 216 |   Names[RTLIB::UINTTOFP_I32_F32] = "__floatunsisf"; | 
 | 217 |   Names[RTLIB::UINTTOFP_I32_F64] = "__floatunsidf"; | 
| Duncan Sands | ac6cece | 2008-07-11 17:00:14 +0000 | [diff] [blame] | 218 |   Names[RTLIB::UINTTOFP_I32_F80] = "__floatunsixf"; | 
 | 219 |   Names[RTLIB::UINTTOFP_I32_PPCF128] = "__floatunsitf"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 220 |   Names[RTLIB::UINTTOFP_I64_F32] = "__floatundisf"; | 
 | 221 |   Names[RTLIB::UINTTOFP_I64_F64] = "__floatundidf"; | 
| Duncan Sands | ac6cece | 2008-07-11 17:00:14 +0000 | [diff] [blame] | 222 |   Names[RTLIB::UINTTOFP_I64_F80] = "__floatundixf"; | 
 | 223 |   Names[RTLIB::UINTTOFP_I64_PPCF128] = "__floatunditf"; | 
 | 224 |   Names[RTLIB::UINTTOFP_I128_F32] = "__floatuntisf"; | 
 | 225 |   Names[RTLIB::UINTTOFP_I128_F64] = "__floatuntidf"; | 
 | 226 |   Names[RTLIB::UINTTOFP_I128_F80] = "__floatuntixf"; | 
 | 227 |   Names[RTLIB::UINTTOFP_I128_PPCF128] = "__floatuntitf"; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 228 |   Names[RTLIB::OEQ_F32] = "__eqsf2"; | 
 | 229 |   Names[RTLIB::OEQ_F64] = "__eqdf2"; | 
 | 230 |   Names[RTLIB::UNE_F32] = "__nesf2"; | 
 | 231 |   Names[RTLIB::UNE_F64] = "__nedf2"; | 
 | 232 |   Names[RTLIB::OGE_F32] = "__gesf2"; | 
 | 233 |   Names[RTLIB::OGE_F64] = "__gedf2"; | 
 | 234 |   Names[RTLIB::OLT_F32] = "__ltsf2"; | 
 | 235 |   Names[RTLIB::OLT_F64] = "__ltdf2"; | 
 | 236 |   Names[RTLIB::OLE_F32] = "__lesf2"; | 
 | 237 |   Names[RTLIB::OLE_F64] = "__ledf2"; | 
 | 238 |   Names[RTLIB::OGT_F32] = "__gtsf2"; | 
 | 239 |   Names[RTLIB::OGT_F64] = "__gtdf2"; | 
 | 240 |   Names[RTLIB::UO_F32] = "__unordsf2"; | 
 | 241 |   Names[RTLIB::UO_F64] = "__unorddf2"; | 
| Evan Cheng | d385fd6 | 2007-01-31 09:29:11 +0000 | [diff] [blame] | 242 |   Names[RTLIB::O_F32] = "__unordsf2"; | 
 | 243 |   Names[RTLIB::O_F64] = "__unorddf2"; | 
| Sanjiv Gupta | a114baa | 2009-07-30 09:12:56 +0000 | [diff] [blame^] | 244 |   Names[RTLIB::MEMCPY] = "memcpy"; | 
 | 245 |   Names[RTLIB::MEMMOVE] = "memmove"; | 
 | 246 |   Names[RTLIB::MEMSET] = "memset"; | 
| Duncan Sands | b0f1e17 | 2009-05-22 20:36:31 +0000 | [diff] [blame] | 247 |   Names[RTLIB::UNWIND_RESUME] = "_Unwind_Resume"; | 
| Evan Cheng | d385fd6 | 2007-01-31 09:29:11 +0000 | [diff] [blame] | 248 | } | 
 | 249 |  | 
| Duncan Sands | b2ff885 | 2008-07-17 02:36:29 +0000 | [diff] [blame] | 250 | /// getFPEXT - Return the FPEXT_*_* value for the given types, or | 
 | 251 | /// UNKNOWN_LIBCALL if there is none. | 
 | 252 | RTLIB::Libcall RTLIB::getFPEXT(MVT OpVT, MVT RetVT) { | 
 | 253 |   if (OpVT == MVT::f32) { | 
 | 254 |     if (RetVT == MVT::f64) | 
 | 255 |       return FPEXT_F32_F64; | 
 | 256 |   } | 
 | 257 |   return UNKNOWN_LIBCALL; | 
 | 258 | } | 
 | 259 |  | 
 | 260 | /// getFPROUND - Return the FPROUND_*_* value for the given types, or | 
 | 261 | /// UNKNOWN_LIBCALL if there is none. | 
 | 262 | RTLIB::Libcall RTLIB::getFPROUND(MVT OpVT, MVT RetVT) { | 
| Bruno Cardoso Lopes | e36bfe6 | 2008-08-07 19:01:24 +0000 | [diff] [blame] | 263 |   if (RetVT == MVT::f32) { | 
 | 264 |     if (OpVT == MVT::f64) | 
| Duncan Sands | b2ff885 | 2008-07-17 02:36:29 +0000 | [diff] [blame] | 265 |       return FPROUND_F64_F32; | 
| Bruno Cardoso Lopes | e36bfe6 | 2008-08-07 19:01:24 +0000 | [diff] [blame] | 266 |     if (OpVT == MVT::f80) | 
 | 267 |       return FPROUND_F80_F32; | 
 | 268 |     if (OpVT == MVT::ppcf128) | 
 | 269 |       return FPROUND_PPCF128_F32; | 
 | 270 |   } else if (RetVT == MVT::f64) { | 
 | 271 |     if (OpVT == MVT::f80) | 
 | 272 |       return FPROUND_F80_F64; | 
 | 273 |     if (OpVT == MVT::ppcf128) | 
 | 274 |       return FPROUND_PPCF128_F64; | 
| Duncan Sands | b2ff885 | 2008-07-17 02:36:29 +0000 | [diff] [blame] | 275 |   } | 
 | 276 |   return UNKNOWN_LIBCALL; | 
 | 277 | } | 
 | 278 |  | 
 | 279 | /// getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or | 
 | 280 | /// UNKNOWN_LIBCALL if there is none. | 
 | 281 | RTLIB::Libcall RTLIB::getFPTOSINT(MVT OpVT, MVT RetVT) { | 
 | 282 |   if (OpVT == MVT::f32) { | 
| Sanjiv Gupta | 8aa207e | 2009-06-16 09:03:58 +0000 | [diff] [blame] | 283 |     if (RetVT == MVT::i8) | 
 | 284 |       return FPTOSINT_F32_I8; | 
 | 285 |     if (RetVT == MVT::i16) | 
 | 286 |       return FPTOSINT_F32_I16; | 
| Duncan Sands | b2ff885 | 2008-07-17 02:36:29 +0000 | [diff] [blame] | 287 |     if (RetVT == MVT::i32) | 
 | 288 |       return FPTOSINT_F32_I32; | 
 | 289 |     if (RetVT == MVT::i64) | 
 | 290 |       return FPTOSINT_F32_I64; | 
 | 291 |     if (RetVT == MVT::i128) | 
 | 292 |       return FPTOSINT_F32_I128; | 
 | 293 |   } else if (OpVT == MVT::f64) { | 
 | 294 |     if (RetVT == MVT::i32) | 
 | 295 |       return FPTOSINT_F64_I32; | 
 | 296 |     if (RetVT == MVT::i64) | 
 | 297 |       return FPTOSINT_F64_I64; | 
 | 298 |     if (RetVT == MVT::i128) | 
 | 299 |       return FPTOSINT_F64_I128; | 
 | 300 |   } else if (OpVT == MVT::f80) { | 
 | 301 |     if (RetVT == MVT::i32) | 
 | 302 |       return FPTOSINT_F80_I32; | 
 | 303 |     if (RetVT == MVT::i64) | 
 | 304 |       return FPTOSINT_F80_I64; | 
 | 305 |     if (RetVT == MVT::i128) | 
 | 306 |       return FPTOSINT_F80_I128; | 
 | 307 |   } else if (OpVT == MVT::ppcf128) { | 
 | 308 |     if (RetVT == MVT::i32) | 
 | 309 |       return FPTOSINT_PPCF128_I32; | 
 | 310 |     if (RetVT == MVT::i64) | 
 | 311 |       return FPTOSINT_PPCF128_I64; | 
 | 312 |     if (RetVT == MVT::i128) | 
 | 313 |       return FPTOSINT_PPCF128_I128; | 
 | 314 |   } | 
 | 315 |   return UNKNOWN_LIBCALL; | 
 | 316 | } | 
 | 317 |  | 
 | 318 | /// getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or | 
 | 319 | /// UNKNOWN_LIBCALL if there is none. | 
 | 320 | RTLIB::Libcall RTLIB::getFPTOUINT(MVT OpVT, MVT RetVT) { | 
 | 321 |   if (OpVT == MVT::f32) { | 
| Sanjiv Gupta | 8aa207e | 2009-06-16 09:03:58 +0000 | [diff] [blame] | 322 |     if (RetVT == MVT::i8) | 
 | 323 |       return FPTOUINT_F32_I8; | 
 | 324 |     if (RetVT == MVT::i16) | 
 | 325 |       return FPTOUINT_F32_I16; | 
| Duncan Sands | b2ff885 | 2008-07-17 02:36:29 +0000 | [diff] [blame] | 326 |     if (RetVT == MVT::i32) | 
 | 327 |       return FPTOUINT_F32_I32; | 
 | 328 |     if (RetVT == MVT::i64) | 
 | 329 |       return FPTOUINT_F32_I64; | 
 | 330 |     if (RetVT == MVT::i128) | 
 | 331 |       return FPTOUINT_F32_I128; | 
 | 332 |   } else if (OpVT == MVT::f64) { | 
 | 333 |     if (RetVT == MVT::i32) | 
 | 334 |       return FPTOUINT_F64_I32; | 
 | 335 |     if (RetVT == MVT::i64) | 
 | 336 |       return FPTOUINT_F64_I64; | 
 | 337 |     if (RetVT == MVT::i128) | 
 | 338 |       return FPTOUINT_F64_I128; | 
 | 339 |   } else if (OpVT == MVT::f80) { | 
 | 340 |     if (RetVT == MVT::i32) | 
 | 341 |       return FPTOUINT_F80_I32; | 
 | 342 |     if (RetVT == MVT::i64) | 
 | 343 |       return FPTOUINT_F80_I64; | 
 | 344 |     if (RetVT == MVT::i128) | 
 | 345 |       return FPTOUINT_F80_I128; | 
 | 346 |   } else if (OpVT == MVT::ppcf128) { | 
 | 347 |     if (RetVT == MVT::i32) | 
 | 348 |       return FPTOUINT_PPCF128_I32; | 
 | 349 |     if (RetVT == MVT::i64) | 
 | 350 |       return FPTOUINT_PPCF128_I64; | 
 | 351 |     if (RetVT == MVT::i128) | 
 | 352 |       return FPTOUINT_PPCF128_I128; | 
 | 353 |   } | 
 | 354 |   return UNKNOWN_LIBCALL; | 
 | 355 | } | 
 | 356 |  | 
 | 357 | /// getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or | 
 | 358 | /// UNKNOWN_LIBCALL if there is none. | 
 | 359 | RTLIB::Libcall RTLIB::getSINTTOFP(MVT OpVT, MVT RetVT) { | 
 | 360 |   if (OpVT == MVT::i32) { | 
 | 361 |     if (RetVT == MVT::f32) | 
 | 362 |       return SINTTOFP_I32_F32; | 
 | 363 |     else if (RetVT == MVT::f64) | 
 | 364 |       return SINTTOFP_I32_F64; | 
 | 365 |     else if (RetVT == MVT::f80) | 
 | 366 |       return SINTTOFP_I32_F80; | 
 | 367 |     else if (RetVT == MVT::ppcf128) | 
 | 368 |       return SINTTOFP_I32_PPCF128; | 
 | 369 |   } else if (OpVT == MVT::i64) { | 
 | 370 |     if (RetVT == MVT::f32) | 
 | 371 |       return SINTTOFP_I64_F32; | 
 | 372 |     else if (RetVT == MVT::f64) | 
 | 373 |       return SINTTOFP_I64_F64; | 
 | 374 |     else if (RetVT == MVT::f80) | 
 | 375 |       return SINTTOFP_I64_F80; | 
 | 376 |     else if (RetVT == MVT::ppcf128) | 
 | 377 |       return SINTTOFP_I64_PPCF128; | 
 | 378 |   } else if (OpVT == MVT::i128) { | 
 | 379 |     if (RetVT == MVT::f32) | 
 | 380 |       return SINTTOFP_I128_F32; | 
 | 381 |     else if (RetVT == MVT::f64) | 
 | 382 |       return SINTTOFP_I128_F64; | 
 | 383 |     else if (RetVT == MVT::f80) | 
 | 384 |       return SINTTOFP_I128_F80; | 
 | 385 |     else if (RetVT == MVT::ppcf128) | 
 | 386 |       return SINTTOFP_I128_PPCF128; | 
 | 387 |   } | 
 | 388 |   return UNKNOWN_LIBCALL; | 
 | 389 | } | 
 | 390 |  | 
 | 391 | /// getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or | 
 | 392 | /// UNKNOWN_LIBCALL if there is none. | 
 | 393 | RTLIB::Libcall RTLIB::getUINTTOFP(MVT OpVT, MVT RetVT) { | 
 | 394 |   if (OpVT == MVT::i32) { | 
 | 395 |     if (RetVT == MVT::f32) | 
 | 396 |       return UINTTOFP_I32_F32; | 
 | 397 |     else if (RetVT == MVT::f64) | 
 | 398 |       return UINTTOFP_I32_F64; | 
 | 399 |     else if (RetVT == MVT::f80) | 
 | 400 |       return UINTTOFP_I32_F80; | 
 | 401 |     else if (RetVT == MVT::ppcf128) | 
 | 402 |       return UINTTOFP_I32_PPCF128; | 
 | 403 |   } else if (OpVT == MVT::i64) { | 
 | 404 |     if (RetVT == MVT::f32) | 
 | 405 |       return UINTTOFP_I64_F32; | 
 | 406 |     else if (RetVT == MVT::f64) | 
 | 407 |       return UINTTOFP_I64_F64; | 
 | 408 |     else if (RetVT == MVT::f80) | 
 | 409 |       return UINTTOFP_I64_F80; | 
 | 410 |     else if (RetVT == MVT::ppcf128) | 
 | 411 |       return UINTTOFP_I64_PPCF128; | 
 | 412 |   } else if (OpVT == MVT::i128) { | 
 | 413 |     if (RetVT == MVT::f32) | 
 | 414 |       return UINTTOFP_I128_F32; | 
 | 415 |     else if (RetVT == MVT::f64) | 
 | 416 |       return UINTTOFP_I128_F64; | 
 | 417 |     else if (RetVT == MVT::f80) | 
 | 418 |       return UINTTOFP_I128_F80; | 
 | 419 |     else if (RetVT == MVT::ppcf128) | 
 | 420 |       return UINTTOFP_I128_PPCF128; | 
 | 421 |   } | 
 | 422 |   return UNKNOWN_LIBCALL; | 
 | 423 | } | 
 | 424 |  | 
| Evan Cheng | d385fd6 | 2007-01-31 09:29:11 +0000 | [diff] [blame] | 425 | /// InitCmpLibcallCCs - Set default comparison libcall CC. | 
 | 426 | /// | 
 | 427 | static void InitCmpLibcallCCs(ISD::CondCode *CCs) { | 
 | 428 |   memset(CCs, ISD::SETCC_INVALID, sizeof(ISD::CondCode)*RTLIB::UNKNOWN_LIBCALL); | 
 | 429 |   CCs[RTLIB::OEQ_F32] = ISD::SETEQ; | 
 | 430 |   CCs[RTLIB::OEQ_F64] = ISD::SETEQ; | 
 | 431 |   CCs[RTLIB::UNE_F32] = ISD::SETNE; | 
 | 432 |   CCs[RTLIB::UNE_F64] = ISD::SETNE; | 
 | 433 |   CCs[RTLIB::OGE_F32] = ISD::SETGE; | 
 | 434 |   CCs[RTLIB::OGE_F64] = ISD::SETGE; | 
 | 435 |   CCs[RTLIB::OLT_F32] = ISD::SETLT; | 
 | 436 |   CCs[RTLIB::OLT_F64] = ISD::SETLT; | 
 | 437 |   CCs[RTLIB::OLE_F32] = ISD::SETLE; | 
 | 438 |   CCs[RTLIB::OLE_F64] = ISD::SETLE; | 
 | 439 |   CCs[RTLIB::OGT_F32] = ISD::SETGT; | 
 | 440 |   CCs[RTLIB::OGT_F64] = ISD::SETGT; | 
 | 441 |   CCs[RTLIB::UO_F32] = ISD::SETNE; | 
 | 442 |   CCs[RTLIB::UO_F64] = ISD::SETNE; | 
 | 443 |   CCs[RTLIB::O_F32] = ISD::SETEQ; | 
 | 444 |   CCs[RTLIB::O_F64] = ISD::SETEQ; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 445 | } | 
 | 446 |  | 
| Chris Lattner | f014412 | 2009-07-28 03:13:23 +0000 | [diff] [blame] | 447 | /// NOTE: The constructor takes ownership of TLOF. | 
 | 448 | TargetLowering::TargetLowering(TargetMachine &tm,TargetLoweringObjectFile *tlof) | 
 | 449 |   : TM(tm), TD(TM.getTargetData()), TLOF(*tlof) { | 
| Chris Lattner | cba82f9 | 2005-01-16 07:28:11 +0000 | [diff] [blame] | 450 |   // All operations default to being supported. | 
 | 451 |   memset(OpActions, 0, sizeof(OpActions)); | 
| Evan Cheng | 0329466 | 2008-10-14 21:26:46 +0000 | [diff] [blame] | 452 |   memset(LoadExtActions, 0, sizeof(LoadExtActions)); | 
| Chris Lattner | ddf8956 | 2008-01-17 19:59:44 +0000 | [diff] [blame] | 453 |   memset(TruncStoreActions, 0, sizeof(TruncStoreActions)); | 
| Chris Lattner | c9133f9 | 2008-01-18 19:36:20 +0000 | [diff] [blame] | 454 |   memset(IndexedModeActions, 0, sizeof(IndexedModeActions)); | 
 | 455 |   memset(ConvertActions, 0, sizeof(ConvertActions)); | 
| Evan Cheng | 7f04268 | 2008-10-15 02:05:31 +0000 | [diff] [blame] | 456 |   memset(CondCodeActions, 0, sizeof(CondCodeActions)); | 
| Dan Gohman | 93f81e2 | 2007-07-09 20:49:44 +0000 | [diff] [blame] | 457 |  | 
| Chris Lattner | 1a3048b | 2007-12-22 20:47:56 +0000 | [diff] [blame] | 458 |   // Set default actions for various operations. | 
| Evan Cheng | 5ff839f | 2006-11-09 18:56:43 +0000 | [diff] [blame] | 459 |   for (unsigned VT = 0; VT != (unsigned)MVT::LAST_VALUETYPE; ++VT) { | 
| Chris Lattner | 1a3048b | 2007-12-22 20:47:56 +0000 | [diff] [blame] | 460 |     // Default all indexed load / store to expand. | 
| Evan Cheng | 5ff839f | 2006-11-09 18:56:43 +0000 | [diff] [blame] | 461 |     for (unsigned IM = (unsigned)ISD::PRE_INC; | 
 | 462 |          IM != (unsigned)ISD::LAST_INDEXED_MODE; ++IM) { | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 463 |       setIndexedLoadAction(IM, (MVT::SimpleValueType)VT, Expand); | 
 | 464 |       setIndexedStoreAction(IM, (MVT::SimpleValueType)VT, Expand); | 
| Evan Cheng | 5ff839f | 2006-11-09 18:56:43 +0000 | [diff] [blame] | 465 |     } | 
| Chris Lattner | 1a3048b | 2007-12-22 20:47:56 +0000 | [diff] [blame] | 466 |      | 
 | 467 |     // These operations default to expand. | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 468 |     setOperationAction(ISD::FGETSIGN, (MVT::SimpleValueType)VT, Expand); | 
| Bob Wilson | 5ee24e5 | 2009-05-01 17:55:32 +0000 | [diff] [blame] | 469 |     setOperationAction(ISD::CONCAT_VECTORS, (MVT::SimpleValueType)VT, Expand); | 
| Evan Cheng | 5ff839f | 2006-11-09 18:56:43 +0000 | [diff] [blame] | 470 |   } | 
| Evan Cheng | d2cde68 | 2008-03-10 19:38:10 +0000 | [diff] [blame] | 471 |  | 
 | 472 |   // Most targets ignore the @llvm.prefetch intrinsic. | 
 | 473 |   setOperationAction(ISD::PREFETCH, MVT::Other, Expand); | 
| Nate Begeman | e179584 | 2008-02-14 08:57:00 +0000 | [diff] [blame] | 474 |    | 
 | 475 |   // ConstantFP nodes default to expand.  Targets can either change this to  | 
 | 476 |   // Legal, in which case all fp constants are legal, or use addLegalFPImmediate | 
 | 477 |   // to optimize expansions for certain constants. | 
 | 478 |   setOperationAction(ISD::ConstantFP, MVT::f32, Expand); | 
 | 479 |   setOperationAction(ISD::ConstantFP, MVT::f64, Expand); | 
 | 480 |   setOperationAction(ISD::ConstantFP, MVT::f80, Expand); | 
| Chris Lattner | 310968c | 2005-01-07 07:44:53 +0000 | [diff] [blame] | 481 |  | 
| Dale Johannesen | 0bb4160 | 2008-09-22 21:57:32 +0000 | [diff] [blame] | 482 |   // These library functions default to expand. | 
 | 483 |   setOperationAction(ISD::FLOG , MVT::f64, Expand); | 
 | 484 |   setOperationAction(ISD::FLOG2, MVT::f64, Expand); | 
 | 485 |   setOperationAction(ISD::FLOG10,MVT::f64, Expand); | 
 | 486 |   setOperationAction(ISD::FEXP , MVT::f64, Expand); | 
 | 487 |   setOperationAction(ISD::FEXP2, MVT::f64, Expand); | 
 | 488 |   setOperationAction(ISD::FLOG , MVT::f32, Expand); | 
 | 489 |   setOperationAction(ISD::FLOG2, MVT::f32, Expand); | 
 | 490 |   setOperationAction(ISD::FLOG10,MVT::f32, Expand); | 
 | 491 |   setOperationAction(ISD::FEXP , MVT::f32, Expand); | 
 | 492 |   setOperationAction(ISD::FEXP2, MVT::f32, Expand); | 
 | 493 |  | 
| Chris Lattner | 41bab0b | 2008-01-15 21:58:08 +0000 | [diff] [blame] | 494 |   // Default ISD::TRAP to expand (which turns it into abort). | 
 | 495 |   setOperationAction(ISD::TRAP, MVT::Other, Expand); | 
 | 496 |      | 
| Owen Anderson | a69571c | 2006-05-03 01:29:57 +0000 | [diff] [blame] | 497 |   IsLittleEndian = TD->isLittleEndian(); | 
| Chris Lattner | cf9668f | 2006-10-06 22:52:08 +0000 | [diff] [blame] | 498 |   UsesGlobalOffsetTable = false; | 
| Scott Michel | 5b8f82e | 2008-03-10 15:42:14 +0000 | [diff] [blame] | 499 |   ShiftAmountTy = PointerTy = getValueType(TD->getIntPtrType()); | 
| Chris Lattner | 310968c | 2005-01-07 07:44:53 +0000 | [diff] [blame] | 500 |   memset(RegClassForVT, 0,MVT::LAST_VALUETYPE*sizeof(TargetRegisterClass*)); | 
| Owen Anderson | 718cb66 | 2007-09-07 04:06:50 +0000 | [diff] [blame] | 501 |   memset(TargetDAGCombineArray, 0, array_lengthof(TargetDAGCombineArray)); | 
| Evan Cheng | a03a5dc | 2006-02-14 08:38:30 +0000 | [diff] [blame] | 502 |   maxStoresPerMemset = maxStoresPerMemcpy = maxStoresPerMemmove = 8; | 
| Reid Spencer | 0f9beca | 2005-08-27 19:09:02 +0000 | [diff] [blame] | 503 |   allowUnalignedMemoryAccesses = false; | 
| Evan Cheng | 6ebf7bc | 2009-05-13 21:42:09 +0000 | [diff] [blame] | 504 |   benefitFromCodePlacementOpt = false; | 
| Anton Korobeynikov | d27a258 | 2006-12-10 23:12:42 +0000 | [diff] [blame] | 505 |   UseUnderscoreSetJmp = false; | 
 | 506 |   UseUnderscoreLongJmp = false; | 
| Chris Lattner | 6618039 | 2007-02-25 01:28:05 +0000 | [diff] [blame] | 507 |   SelectIsExpensive = false; | 
| Nate Begeman | 405e3ec | 2005-10-21 00:02:42 +0000 | [diff] [blame] | 508 |   IntDivIsCheap = false; | 
 | 509 |   Pow2DivIsCheap = false; | 
| Chris Lattner | ee4a765 | 2006-01-25 18:57:15 +0000 | [diff] [blame] | 510 |   StackPointerRegisterToSaveRestore = 0; | 
| Jim Laskey | 9bb3c93 | 2007-02-22 18:04:49 +0000 | [diff] [blame] | 511 |   ExceptionPointerRegister = 0; | 
 | 512 |   ExceptionSelectorRegister = 0; | 
| Duncan Sands | 0322808 | 2008-11-23 15:47:28 +0000 | [diff] [blame] | 513 |   BooleanContents = UndefinedBooleanContent; | 
| Evan Cheng | 0577a22 | 2006-01-25 18:52:42 +0000 | [diff] [blame] | 514 |   SchedPreferenceInfo = SchedulingForLatency; | 
| Chris Lattner | 7acf5f3 | 2006-09-05 17:39:15 +0000 | [diff] [blame] | 515 |   JumpBufSize = 0; | 
| Duraid Madina | 0c9e0ff | 2006-09-04 07:44:11 +0000 | [diff] [blame] | 516 |   JumpBufAlignment = 0; | 
| Evan Cheng | d60483e | 2007-05-16 23:45:53 +0000 | [diff] [blame] | 517 |   IfCvtBlockSizeLimit = 2; | 
| Evan Cheng | fb8075d | 2008-02-28 00:43:03 +0000 | [diff] [blame] | 518 |   IfCvtDupBlockSizeLimit = 0; | 
 | 519 |   PrefLoopAlignment = 0; | 
| Evan Cheng | 5696622 | 2007-01-12 02:11:51 +0000 | [diff] [blame] | 520 |  | 
 | 521 |   InitLibcallNames(LibcallRoutineNames); | 
| Evan Cheng | d385fd6 | 2007-01-31 09:29:11 +0000 | [diff] [blame] | 522 |   InitCmpLibcallCCs(CmpLibcallCCs); | 
| Dan Gohman | c3b0b5c | 2007-09-25 15:10:49 +0000 | [diff] [blame] | 523 |  | 
 | 524 |   // Tell Legalize whether the assembler supports DEBUG_LOC. | 
| Matthijs Kooijman | d9d0778 | 2008-10-13 12:41:46 +0000 | [diff] [blame] | 525 |   const TargetAsmInfo *TASM = TM.getTargetAsmInfo(); | 
 | 526 |   if (!TASM || !TASM->hasDotLocAndDotFile()) | 
| Dan Gohman | c3b0b5c | 2007-09-25 15:10:49 +0000 | [diff] [blame] | 527 |     setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); | 
| Chris Lattner | 310968c | 2005-01-07 07:44:53 +0000 | [diff] [blame] | 528 | } | 
 | 529 |  | 
| Chris Lattner | f014412 | 2009-07-28 03:13:23 +0000 | [diff] [blame] | 530 | TargetLowering::~TargetLowering() { | 
 | 531 |   delete &TLOF; | 
 | 532 | } | 
| Chris Lattner | cba82f9 | 2005-01-16 07:28:11 +0000 | [diff] [blame] | 533 |  | 
| Chris Lattner | 310968c | 2005-01-07 07:44:53 +0000 | [diff] [blame] | 534 | /// computeRegisterProperties - Once all of the register classes are added, | 
 | 535 | /// this allows us to compute derived properties we expose. | 
 | 536 | void TargetLowering::computeRegisterProperties() { | 
| David Greene | f2e19d5 | 2009-06-24 19:41:55 +0000 | [diff] [blame] | 537 |   assert(MVT::LAST_VALUETYPE <= MVT::MAX_ALLOWED_VALUETYPE && | 
| Chris Lattner | bb97d81 | 2005-01-16 01:10:58 +0000 | [diff] [blame] | 538 |          "Too many value types for ValueTypeActions to hold!"); | 
 | 539 |  | 
| Dan Gohman | b6f5b00 | 2007-06-28 23:29:44 +0000 | [diff] [blame] | 540 |   // Everything defaults to needing one register. | 
 | 541 |   for (unsigned i = 0; i != MVT::LAST_VALUETYPE; ++i) { | 
| Dan Gohman | b9f1019 | 2007-06-21 14:42:22 +0000 | [diff] [blame] | 542 |     NumRegistersForVT[i] = 1; | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 543 |     RegisterTypeForVT[i] = TransformToType[i] = (MVT::SimpleValueType)i; | 
| Dan Gohman | b6f5b00 | 2007-06-28 23:29:44 +0000 | [diff] [blame] | 544 |   } | 
 | 545 |   // ...except isVoid, which doesn't need any registers. | 
 | 546 |   NumRegistersForVT[MVT::isVoid] = 0; | 
| Misha Brukman | f976c85 | 2005-04-21 22:55:34 +0000 | [diff] [blame] | 547 |  | 
| Chris Lattner | 310968c | 2005-01-07 07:44:53 +0000 | [diff] [blame] | 548 |   // Find the largest integer register class. | 
| Duncan Sands | 8930763 | 2008-06-09 15:48:25 +0000 | [diff] [blame] | 549 |   unsigned LargestIntReg = MVT::LAST_INTEGER_VALUETYPE; | 
| Chris Lattner | 310968c | 2005-01-07 07:44:53 +0000 | [diff] [blame] | 550 |   for (; RegClassForVT[LargestIntReg] == 0; --LargestIntReg) | 
 | 551 |     assert(LargestIntReg != MVT::i1 && "No integer registers defined!"); | 
 | 552 |  | 
 | 553 |   // Every integer value type larger than this largest register takes twice as | 
 | 554 |   // many registers to represent as the previous ValueType. | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 555 |   for (unsigned ExpandedReg = LargestIntReg + 1; ; ++ExpandedReg) { | 
 | 556 |     MVT EVT = (MVT::SimpleValueType)ExpandedReg; | 
 | 557 |     if (!EVT.isInteger()) | 
 | 558 |       break; | 
| Dan Gohman | b9f1019 | 2007-06-21 14:42:22 +0000 | [diff] [blame] | 559 |     NumRegistersForVT[ExpandedReg] = 2*NumRegistersForVT[ExpandedReg-1]; | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 560 |     RegisterTypeForVT[ExpandedReg] = (MVT::SimpleValueType)LargestIntReg; | 
 | 561 |     TransformToType[ExpandedReg] = (MVT::SimpleValueType)(ExpandedReg - 1); | 
 | 562 |     ValueTypeActions.setTypeAction(EVT, Expand); | 
| Evan Cheng | 1a8f1fe | 2006-12-09 02:42:38 +0000 | [diff] [blame] | 563 |   } | 
| Dan Gohman | b6f5b00 | 2007-06-28 23:29:44 +0000 | [diff] [blame] | 564 |  | 
 | 565 |   // Inspect all of the ValueType's smaller than the largest integer | 
 | 566 |   // register to see which ones need promotion. | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 567 |   unsigned LegalIntReg = LargestIntReg; | 
 | 568 |   for (unsigned IntReg = LargestIntReg - 1; | 
 | 569 |        IntReg >= (unsigned)MVT::i1; --IntReg) { | 
 | 570 |     MVT IVT = (MVT::SimpleValueType)IntReg; | 
 | 571 |     if (isTypeLegal(IVT)) { | 
| Dan Gohman | b6f5b00 | 2007-06-28 23:29:44 +0000 | [diff] [blame] | 572 |       LegalIntReg = IntReg; | 
 | 573 |     } else { | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 574 |       RegisterTypeForVT[IntReg] = TransformToType[IntReg] = | 
 | 575 |         (MVT::SimpleValueType)LegalIntReg; | 
 | 576 |       ValueTypeActions.setTypeAction(IVT, Promote); | 
| Dan Gohman | b6f5b00 | 2007-06-28 23:29:44 +0000 | [diff] [blame] | 577 |     } | 
 | 578 |   } | 
 | 579 |  | 
| Dale Johannesen | 161e897 | 2007-10-05 20:04:43 +0000 | [diff] [blame] | 580 |   // ppcf128 type is really two f64's. | 
 | 581 |   if (!isTypeLegal(MVT::ppcf128)) { | 
 | 582 |     NumRegistersForVT[MVT::ppcf128] = 2*NumRegistersForVT[MVT::f64]; | 
 | 583 |     RegisterTypeForVT[MVT::ppcf128] = MVT::f64; | 
 | 584 |     TransformToType[MVT::ppcf128] = MVT::f64; | 
 | 585 |     ValueTypeActions.setTypeAction(MVT::ppcf128, Expand); | 
 | 586 |   }     | 
 | 587 |  | 
| Dan Gohman | b6f5b00 | 2007-06-28 23:29:44 +0000 | [diff] [blame] | 588 |   // Decide how to handle f64. If the target does not have native f64 support, | 
 | 589 |   // expand it to i64 and we will be generating soft float library calls. | 
 | 590 |   if (!isTypeLegal(MVT::f64)) { | 
 | 591 |     NumRegistersForVT[MVT::f64] = NumRegistersForVT[MVT::i64]; | 
 | 592 |     RegisterTypeForVT[MVT::f64] = RegisterTypeForVT[MVT::i64]; | 
 | 593 |     TransformToType[MVT::f64] = MVT::i64; | 
 | 594 |     ValueTypeActions.setTypeAction(MVT::f64, Expand); | 
 | 595 |   } | 
 | 596 |  | 
 | 597 |   // Decide how to handle f32. If the target does not have native support for | 
 | 598 |   // f32, promote it to f64 if it is legal. Otherwise, expand it to i32. | 
 | 599 |   if (!isTypeLegal(MVT::f32)) { | 
 | 600 |     if (isTypeLegal(MVT::f64)) { | 
 | 601 |       NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::f64]; | 
 | 602 |       RegisterTypeForVT[MVT::f32] = RegisterTypeForVT[MVT::f64]; | 
 | 603 |       TransformToType[MVT::f32] = MVT::f64; | 
 | 604 |       ValueTypeActions.setTypeAction(MVT::f32, Promote); | 
 | 605 |     } else { | 
 | 606 |       NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::i32]; | 
 | 607 |       RegisterTypeForVT[MVT::f32] = RegisterTypeForVT[MVT::i32]; | 
 | 608 |       TransformToType[MVT::f32] = MVT::i32; | 
 | 609 |       ValueTypeActions.setTypeAction(MVT::f32, Expand); | 
 | 610 |     } | 
| Evan Cheng | 1a8f1fe | 2006-12-09 02:42:38 +0000 | [diff] [blame] | 611 |   } | 
| Nate Begeman | 4ef3b81 | 2005-11-22 01:29:36 +0000 | [diff] [blame] | 612 |    | 
| Dan Gohman | b6f5b00 | 2007-06-28 23:29:44 +0000 | [diff] [blame] | 613 |   // Loop over all of the vector value types to see which need transformations. | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 614 |   for (unsigned i = MVT::FIRST_VECTOR_VALUETYPE; | 
 | 615 |        i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) { | 
 | 616 |     MVT VT = (MVT::SimpleValueType)i; | 
 | 617 |     if (!isTypeLegal(VT)) { | 
 | 618 |       MVT IntermediateVT, RegisterVT; | 
| Dan Gohman | b6f5b00 | 2007-06-28 23:29:44 +0000 | [diff] [blame] | 619 |       unsigned NumIntermediates; | 
 | 620 |       NumRegistersForVT[i] = | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 621 |         getVectorTypeBreakdown(VT, | 
| Dan Gohman | b6f5b00 | 2007-06-28 23:29:44 +0000 | [diff] [blame] | 622 |                                IntermediateVT, NumIntermediates, | 
 | 623 |                                RegisterVT); | 
 | 624 |       RegisterTypeForVT[i] = RegisterVT; | 
| Mon P Wang | 87c8a8f | 2008-12-18 20:03:17 +0000 | [diff] [blame] | 625 |        | 
 | 626 |       // Determine if there is a legal wider type. | 
 | 627 |       bool IsLegalWiderType = false; | 
 | 628 |       MVT EltVT = VT.getVectorElementType(); | 
 | 629 |       unsigned NElts = VT.getVectorNumElements(); | 
 | 630 |       for (unsigned nVT = i+1; nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) { | 
 | 631 |         MVT SVT = (MVT::SimpleValueType)nVT; | 
 | 632 |         if (isTypeLegal(SVT) && SVT.getVectorElementType() == EltVT && | 
 | 633 |             SVT.getVectorNumElements() > NElts) { | 
 | 634 |           TransformToType[i] = SVT; | 
 | 635 |           ValueTypeActions.setTypeAction(VT, Promote); | 
 | 636 |           IsLegalWiderType = true; | 
 | 637 |           break; | 
 | 638 |         } | 
 | 639 |       } | 
 | 640 |       if (!IsLegalWiderType) { | 
 | 641 |         MVT NVT = VT.getPow2VectorType(); | 
 | 642 |         if (NVT == VT) { | 
 | 643 |           // Type is already a power of 2.  The default action is to split. | 
 | 644 |           TransformToType[i] = MVT::Other; | 
 | 645 |           ValueTypeActions.setTypeAction(VT, Expand); | 
 | 646 |         } else { | 
 | 647 |           TransformToType[i] = NVT; | 
 | 648 |           ValueTypeActions.setTypeAction(VT, Promote); | 
 | 649 |         } | 
 | 650 |       } | 
| Dan Gohman | 7f32156 | 2007-06-25 16:23:39 +0000 | [diff] [blame] | 651 |     } | 
| Chris Lattner | 3a593584 | 2006-03-16 19:50:01 +0000 | [diff] [blame] | 652 |   } | 
| Chris Lattner | bb97d81 | 2005-01-16 01:10:58 +0000 | [diff] [blame] | 653 | } | 
| Chris Lattner | cba82f9 | 2005-01-16 07:28:11 +0000 | [diff] [blame] | 654 |  | 
| Evan Cheng | 7226158 | 2005-12-20 06:22:03 +0000 | [diff] [blame] | 655 | const char *TargetLowering::getTargetNodeName(unsigned Opcode) const { | 
 | 656 |   return NULL; | 
 | 657 | } | 
| Evan Cheng | 3a03ebb | 2005-12-21 23:05:39 +0000 | [diff] [blame] | 658 |  | 
| Scott Michel | 5b8f82e | 2008-03-10 15:42:14 +0000 | [diff] [blame] | 659 |  | 
| Duncan Sands | 5480c04 | 2009-01-01 15:52:00 +0000 | [diff] [blame] | 660 | MVT TargetLowering::getSetCCResultType(MVT VT) const { | 
| Scott Michel | 5b8f82e | 2008-03-10 15:42:14 +0000 | [diff] [blame] | 661 |   return getValueType(TD->getIntPtrType()); | 
 | 662 | } | 
 | 663 |  | 
 | 664 |  | 
| Dan Gohman | 7f32156 | 2007-06-25 16:23:39 +0000 | [diff] [blame] | 665 | /// getVectorTypeBreakdown - Vector types are broken down into some number of | 
 | 666 | /// legal first class types.  For example, MVT::v8f32 maps to 2 MVT::v4f32 | 
| Chris Lattner | dc87929 | 2006-03-31 00:28:56 +0000 | [diff] [blame] | 667 | /// with Altivec or SSE1, or 8 promoted MVT::f64 values with the X86 FP stack. | 
| Dan Gohman | 7f32156 | 2007-06-25 16:23:39 +0000 | [diff] [blame] | 668 | /// Similarly, MVT::v2i64 turns into 4 MVT::i32 values with both PPC and X86. | 
| Chris Lattner | dc87929 | 2006-03-31 00:28:56 +0000 | [diff] [blame] | 669 | /// | 
| Dan Gohman | 7f32156 | 2007-06-25 16:23:39 +0000 | [diff] [blame] | 670 | /// This method returns the number of registers needed, and the VT for each | 
| Dan Gohman | b6f5b00 | 2007-06-28 23:29:44 +0000 | [diff] [blame] | 671 | /// register.  It also returns the VT and quantity of the intermediate values | 
 | 672 | /// before they are promoted/expanded. | 
| Chris Lattner | dc87929 | 2006-03-31 00:28:56 +0000 | [diff] [blame] | 673 | /// | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 674 | unsigned TargetLowering::getVectorTypeBreakdown(MVT VT, | 
 | 675 |                                                 MVT &IntermediateVT, | 
| Dan Gohman | b6f5b00 | 2007-06-28 23:29:44 +0000 | [diff] [blame] | 676 |                                                 unsigned &NumIntermediates, | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 677 |                                       MVT &RegisterVT) const { | 
| Chris Lattner | dc87929 | 2006-03-31 00:28:56 +0000 | [diff] [blame] | 678 |   // Figure out the right, legal destination reg to copy into. | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 679 |   unsigned NumElts = VT.getVectorNumElements(); | 
 | 680 |   MVT EltTy = VT.getVectorElementType(); | 
| Chris Lattner | dc87929 | 2006-03-31 00:28:56 +0000 | [diff] [blame] | 681 |    | 
 | 682 |   unsigned NumVectorRegs = 1; | 
 | 683 |    | 
| Nate Begeman | d73ab88 | 2007-11-27 19:28:48 +0000 | [diff] [blame] | 684 |   // FIXME: We don't support non-power-of-2-sized vectors for now.  Ideally we  | 
 | 685 |   // could break down into LHS/RHS like LegalizeDAG does. | 
 | 686 |   if (!isPowerOf2_32(NumElts)) { | 
 | 687 |     NumVectorRegs = NumElts; | 
 | 688 |     NumElts = 1; | 
 | 689 |   } | 
 | 690 |    | 
| Chris Lattner | dc87929 | 2006-03-31 00:28:56 +0000 | [diff] [blame] | 691 |   // Divide the input until we get to a supported size.  This will always | 
 | 692 |   // end with a scalar if the target doesn't support vectors. | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 693 |   while (NumElts > 1 && !isTypeLegal(MVT::getVectorVT(EltTy, NumElts))) { | 
| Chris Lattner | dc87929 | 2006-03-31 00:28:56 +0000 | [diff] [blame] | 694 |     NumElts >>= 1; | 
 | 695 |     NumVectorRegs <<= 1; | 
 | 696 |   } | 
| Dan Gohman | b6f5b00 | 2007-06-28 23:29:44 +0000 | [diff] [blame] | 697 |  | 
 | 698 |   NumIntermediates = NumVectorRegs; | 
| Chris Lattner | dc87929 | 2006-03-31 00:28:56 +0000 | [diff] [blame] | 699 |    | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 700 |   MVT NewVT = MVT::getVectorVT(EltTy, NumElts); | 
| Dan Gohman | 7f32156 | 2007-06-25 16:23:39 +0000 | [diff] [blame] | 701 |   if (!isTypeLegal(NewVT)) | 
 | 702 |     NewVT = EltTy; | 
| Dan Gohman | b6f5b00 | 2007-06-28 23:29:44 +0000 | [diff] [blame] | 703 |   IntermediateVT = NewVT; | 
| Chris Lattner | dc87929 | 2006-03-31 00:28:56 +0000 | [diff] [blame] | 704 |  | 
| Chris Lattner | 2f992d1 | 2009-04-18 20:48:07 +0000 | [diff] [blame] | 705 |   MVT DestVT = getRegisterType(NewVT); | 
| Dan Gohman | b6f5b00 | 2007-06-28 23:29:44 +0000 | [diff] [blame] | 706 |   RegisterVT = DestVT; | 
| Duncan Sands | 8e4eb09 | 2008-06-08 20:54:56 +0000 | [diff] [blame] | 707 |   if (DestVT.bitsLT(NewVT)) { | 
| Chris Lattner | dc87929 | 2006-03-31 00:28:56 +0000 | [diff] [blame] | 708 |     // Value is expanded, e.g. i64 -> i16. | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 709 |     return NumVectorRegs*(NewVT.getSizeInBits()/DestVT.getSizeInBits()); | 
| Chris Lattner | dc87929 | 2006-03-31 00:28:56 +0000 | [diff] [blame] | 710 |   } else { | 
 | 711 |     // Otherwise, promotion or legal types use the same number of registers as | 
 | 712 |     // the vector decimated to the appropriate level. | 
| Chris Lattner | 79227e2 | 2006-03-31 00:46:36 +0000 | [diff] [blame] | 713 |     return NumVectorRegs; | 
| Chris Lattner | dc87929 | 2006-03-31 00:28:56 +0000 | [diff] [blame] | 714 |   } | 
 | 715 |    | 
| Evan Cheng | e9b3da1 | 2006-05-17 18:10:06 +0000 | [diff] [blame] | 716 |   return 1; | 
| Chris Lattner | dc87929 | 2006-03-31 00:28:56 +0000 | [diff] [blame] | 717 | } | 
 | 718 |  | 
| Mon P Wang | 0c39719 | 2008-10-30 08:01:45 +0000 | [diff] [blame] | 719 | /// getWidenVectorType: given a vector type, returns the type to widen to | 
 | 720 | /// (e.g., v7i8 to v8i8). If the vector type is legal, it returns itself. | 
 | 721 | /// If there is no vector type that we want to widen to, returns MVT::Other | 
| Mon P Wang | f007a8b | 2008-11-06 05:31:54 +0000 | [diff] [blame] | 722 | /// When and where to widen is target dependent based on the cost of | 
| Mon P Wang | 0c39719 | 2008-10-30 08:01:45 +0000 | [diff] [blame] | 723 | /// scalarizing vs using the wider vector type. | 
| Dan Gohman | 65b7f27 | 2009-01-15 17:39:39 +0000 | [diff] [blame] | 724 | MVT TargetLowering::getWidenVectorType(MVT VT) const { | 
| Mon P Wang | 0c39719 | 2008-10-30 08:01:45 +0000 | [diff] [blame] | 725 |   assert(VT.isVector()); | 
 | 726 |   if (isTypeLegal(VT)) | 
 | 727 |     return VT; | 
 | 728 |   | 
 | 729 |   // Default is not to widen until moved to LegalizeTypes | 
 | 730 |   return MVT::Other; | 
 | 731 | } | 
 | 732 |  | 
| Evan Cheng | 3ae0543 | 2008-01-24 00:22:01 +0000 | [diff] [blame] | 733 | /// getByValTypeAlignment - Return the desired alignment for ByVal aggregate | 
| Dale Johannesen | 28d08fd | 2008-02-28 22:31:51 +0000 | [diff] [blame] | 734 | /// function arguments in the caller parameter area.  This is the actual | 
 | 735 | /// alignment, not its logarithm. | 
| Evan Cheng | 3ae0543 | 2008-01-24 00:22:01 +0000 | [diff] [blame] | 736 | unsigned TargetLowering::getByValTypeAlignment(const Type *Ty) const { | 
| Dale Johannesen | 28d08fd | 2008-02-28 22:31:51 +0000 | [diff] [blame] | 737 |   return TD->getCallFrameTypeAlignment(Ty); | 
| Evan Cheng | 3ae0543 | 2008-01-24 00:22:01 +0000 | [diff] [blame] | 738 | } | 
 | 739 |  | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 740 | SDValue TargetLowering::getPICJumpTableRelocBase(SDValue Table, | 
 | 741 |                                                  SelectionDAG &DAG) const { | 
| Evan Cheng | cc41586 | 2007-11-09 01:32:10 +0000 | [diff] [blame] | 742 |   if (usesGlobalOffsetTable()) | 
| Dale Johannesen | b300d2a | 2009-02-07 00:55:49 +0000 | [diff] [blame] | 743 |     return DAG.getGLOBAL_OFFSET_TABLE(getPointerTy()); | 
| Evan Cheng | cc41586 | 2007-11-09 01:32:10 +0000 | [diff] [blame] | 744 |   return Table; | 
 | 745 | } | 
 | 746 |  | 
| Dan Gohman | 6520e20 | 2008-10-18 02:06:02 +0000 | [diff] [blame] | 747 | bool | 
 | 748 | TargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const { | 
 | 749 |   // Assume that everything is safe in static mode. | 
 | 750 |   if (getTargetMachine().getRelocationModel() == Reloc::Static) | 
 | 751 |     return true; | 
 | 752 |  | 
 | 753 |   // In dynamic-no-pic mode, assume that known defined values are safe. | 
 | 754 |   if (getTargetMachine().getRelocationModel() == Reloc::DynamicNoPIC && | 
 | 755 |       GA && | 
 | 756 |       !GA->getGlobal()->isDeclaration() && | 
| Duncan Sands | 667d4b8 | 2009-03-07 15:45:40 +0000 | [diff] [blame] | 757 |       !GA->getGlobal()->isWeakForLinker()) | 
| Dan Gohman | 6520e20 | 2008-10-18 02:06:02 +0000 | [diff] [blame] | 758 |     return true; | 
 | 759 |  | 
 | 760 |   // Otherwise assume nothing is safe. | 
 | 761 |   return false; | 
 | 762 | } | 
 | 763 |  | 
| Chris Lattner | eb8146b | 2006-02-04 02:13:02 +0000 | [diff] [blame] | 764 | //===----------------------------------------------------------------------===// | 
 | 765 | //  Optimization Methods | 
 | 766 | //===----------------------------------------------------------------------===// | 
 | 767 |  | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 768 | /// ShrinkDemandedConstant - Check to see if the specified operand of the  | 
 | 769 | /// specified instruction is a constant integer.  If so, check to see if there | 
 | 770 | /// are any bits set in the constant that are not demanded.  If so, shrink the | 
 | 771 | /// constant and return true. | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 772 | bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(SDValue Op,  | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 773 |                                                         const APInt &Demanded) { | 
| Dale Johannesen | de06470 | 2009-02-06 21:50:26 +0000 | [diff] [blame] | 774 |   DebugLoc dl = Op.getDebugLoc(); | 
| Bill Wendling | 36ae6c1 | 2009-03-04 00:18:06 +0000 | [diff] [blame] | 775 |  | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 776 |   // FIXME: ISD::SELECT, ISD::SELECT_CC | 
| Dan Gohman | e5af2d3 | 2009-01-29 01:59:02 +0000 | [diff] [blame] | 777 |   switch (Op.getOpcode()) { | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 778 |   default: break; | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 779 |   case ISD::XOR: | 
| Bill Wendling | 36ae6c1 | 2009-03-04 00:18:06 +0000 | [diff] [blame] | 780 |   case ISD::AND: | 
 | 781 |   case ISD::OR: { | 
 | 782 |     ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1)); | 
 | 783 |     if (!C) return false; | 
 | 784 |  | 
 | 785 |     if (Op.getOpcode() == ISD::XOR && | 
 | 786 |         (C->getAPIntValue() | (~Demanded)).isAllOnesValue()) | 
 | 787 |       return false; | 
 | 788 |  | 
 | 789 |     // if we can expand it to have all bits set, do it | 
 | 790 |     if (C->getAPIntValue().intersects(~Demanded)) { | 
 | 791 |       MVT VT = Op.getValueType(); | 
 | 792 |       SDValue New = DAG.getNode(Op.getOpcode(), dl, VT, Op.getOperand(0), | 
 | 793 |                                 DAG.getConstant(Demanded & | 
 | 794 |                                                 C->getAPIntValue(),  | 
 | 795 |                                                 VT)); | 
 | 796 |       return CombineTo(Op, New); | 
 | 797 |     } | 
 | 798 |  | 
| Nate Begeman | de99629 | 2006-02-03 22:24:05 +0000 | [diff] [blame] | 799 |     break; | 
 | 800 |   } | 
| Bill Wendling | 36ae6c1 | 2009-03-04 00:18:06 +0000 | [diff] [blame] | 801 |   } | 
 | 802 |  | 
| Nate Begeman | de99629 | 2006-02-03 22:24:05 +0000 | [diff] [blame] | 803 |   return false; | 
 | 804 | } | 
| Chris Lattner | c6fd6cd | 2006-01-30 04:09:27 +0000 | [diff] [blame] | 805 |  | 
| Dan Gohman | 97121ba | 2009-04-08 00:15:30 +0000 | [diff] [blame] | 806 | /// ShrinkDemandedOp - Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the | 
 | 807 | /// casts are free.  This uses isZExtFree and ZERO_EXTEND for the widening | 
 | 808 | /// cast, but it could be generalized for targets with other types of | 
 | 809 | /// implicit widening casts. | 
 | 810 | bool | 
 | 811 | TargetLowering::TargetLoweringOpt::ShrinkDemandedOp(SDValue Op, | 
 | 812 |                                                     unsigned BitWidth, | 
 | 813 |                                                     const APInt &Demanded, | 
 | 814 |                                                     DebugLoc dl) { | 
 | 815 |   assert(Op.getNumOperands() == 2 && | 
 | 816 |          "ShrinkDemandedOp only supports binary operators!"); | 
 | 817 |   assert(Op.getNode()->getNumValues() == 1 && | 
 | 818 |          "ShrinkDemandedOp only supports nodes with one result!"); | 
 | 819 |  | 
 | 820 |   // Don't do this if the node has another user, which may require the | 
 | 821 |   // full value. | 
 | 822 |   if (!Op.getNode()->hasOneUse()) | 
 | 823 |     return false; | 
 | 824 |  | 
 | 825 |   // Search for the smallest integer type with free casts to and from | 
 | 826 |   // Op's type. For expedience, just check power-of-2 integer types. | 
 | 827 |   const TargetLowering &TLI = DAG.getTargetLoweringInfo(); | 
 | 828 |   unsigned SmallVTBits = BitWidth - Demanded.countLeadingZeros(); | 
 | 829 |   if (!isPowerOf2_32(SmallVTBits)) | 
 | 830 |     SmallVTBits = NextPowerOf2(SmallVTBits); | 
 | 831 |   for (; SmallVTBits < BitWidth; SmallVTBits = NextPowerOf2(SmallVTBits)) { | 
 | 832 |     MVT SmallVT = MVT::getIntegerVT(SmallVTBits); | 
 | 833 |     if (TLI.isTruncateFree(Op.getValueType(), SmallVT) && | 
 | 834 |         TLI.isZExtFree(SmallVT, Op.getValueType())) { | 
 | 835 |       // We found a type with free casts. | 
 | 836 |       SDValue X = DAG.getNode(Op.getOpcode(), dl, SmallVT, | 
 | 837 |                               DAG.getNode(ISD::TRUNCATE, dl, SmallVT, | 
 | 838 |                                           Op.getNode()->getOperand(0)), | 
 | 839 |                               DAG.getNode(ISD::TRUNCATE, dl, SmallVT, | 
 | 840 |                                           Op.getNode()->getOperand(1))); | 
 | 841 |       SDValue Z = DAG.getNode(ISD::ZERO_EXTEND, dl, Op.getValueType(), X); | 
 | 842 |       return CombineTo(Op, Z); | 
 | 843 |     } | 
 | 844 |   } | 
 | 845 |   return false; | 
 | 846 | } | 
 | 847 |  | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 848 | /// SimplifyDemandedBits - Look at Op.  At this point, we know that only the | 
 | 849 | /// DemandedMask bits of the result of Op are ever used downstream.  If we can | 
 | 850 | /// use this information to simplify Op, create a new simplified DAG node and | 
 | 851 | /// return true, returning the original and new nodes in Old and New. Otherwise, | 
 | 852 | /// analyze the expression and return a mask of KnownOne and KnownZero bits for | 
 | 853 | /// the expression (used to simplify the caller).  The KnownZero/One bits may | 
 | 854 | /// only be accurate for those bits in the DemandedMask. | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 855 | bool TargetLowering::SimplifyDemandedBits(SDValue Op, | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 856 |                                           const APInt &DemandedMask, | 
 | 857 |                                           APInt &KnownZero, | 
 | 858 |                                           APInt &KnownOne, | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 859 |                                           TargetLoweringOpt &TLO, | 
 | 860 |                                           unsigned Depth) const { | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 861 |   unsigned BitWidth = DemandedMask.getBitWidth(); | 
 | 862 |   assert(Op.getValueSizeInBits() == BitWidth && | 
 | 863 |          "Mask size mismatches value type size!"); | 
 | 864 |   APInt NewMask = DemandedMask; | 
| Dale Johannesen | 6f38cb6 | 2009-02-07 19:59:05 +0000 | [diff] [blame] | 865 |   DebugLoc dl = Op.getDebugLoc(); | 
| Chris Lattner | 3fc5b01 | 2007-05-17 18:19:23 +0000 | [diff] [blame] | 866 |  | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 867 |   // Don't know anything. | 
 | 868 |   KnownZero = KnownOne = APInt(BitWidth, 0); | 
 | 869 |  | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 870 |   // Other users may use these bits. | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 871 |   if (!Op.getNode()->hasOneUse()) {  | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 872 |     if (Depth != 0) { | 
 | 873 |       // If not at the root, Just compute the KnownZero/KnownOne bits to  | 
 | 874 |       // simplify things downstream. | 
| Dan Gohman | ea859be | 2007-06-22 14:59:07 +0000 | [diff] [blame] | 875 |       TLO.DAG.ComputeMaskedBits(Op, DemandedMask, KnownZero, KnownOne, Depth); | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 876 |       return false; | 
 | 877 |     } | 
 | 878 |     // If this is the root being simplified, allow it to have multiple uses, | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 879 |     // just set the NewMask to all bits. | 
 | 880 |     NewMask = APInt::getAllOnesValue(BitWidth); | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 881 |   } else if (DemandedMask == 0) {    | 
 | 882 |     // Not demanding any bits from Op. | 
 | 883 |     if (Op.getOpcode() != ISD::UNDEF) | 
| Dale Johannesen | e8d7230 | 2009-02-06 23:05:02 +0000 | [diff] [blame] | 884 |       return TLO.CombineTo(Op, TLO.DAG.getUNDEF(Op.getValueType())); | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 885 |     return false; | 
 | 886 |   } else if (Depth == 6) {        // Limit search depth. | 
 | 887 |     return false; | 
 | 888 |   } | 
 | 889 |  | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 890 |   APInt KnownZero2, KnownOne2, KnownZeroOut, KnownOneOut; | 
| Chris Lattner | c6fd6cd | 2006-01-30 04:09:27 +0000 | [diff] [blame] | 891 |   switch (Op.getOpcode()) { | 
 | 892 |   case ISD::Constant: | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 893 |     // We know all of the bits for a constant! | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 894 |     KnownOne = cast<ConstantSDNode>(Op)->getAPIntValue() & NewMask; | 
 | 895 |     KnownZero = ~KnownOne & NewMask; | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 896 |     return false;   // Don't fall through, will infinitely loop. | 
| Chris Lattner | c6fd6cd | 2006-01-30 04:09:27 +0000 | [diff] [blame] | 897 |   case ISD::AND: | 
| Chris Lattner | 81cd355 | 2006-02-27 00:36:27 +0000 | [diff] [blame] | 898 |     // If the RHS is a constant, check to see if the LHS would be zero without | 
 | 899 |     // using the bits from the RHS.  Below, we use knowledge about the RHS to | 
 | 900 |     // simplify the LHS, here we're using information from the LHS to simplify | 
 | 901 |     // the RHS. | 
 | 902 |     if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 903 |       APInt LHSZero, LHSOne; | 
 | 904 |       TLO.DAG.ComputeMaskedBits(Op.getOperand(0), NewMask, | 
| Dan Gohman | ea859be | 2007-06-22 14:59:07 +0000 | [diff] [blame] | 905 |                                 LHSZero, LHSOne, Depth+1); | 
| Chris Lattner | 81cd355 | 2006-02-27 00:36:27 +0000 | [diff] [blame] | 906 |       // If the LHS already has zeros where RHSC does, this and is dead. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 907 |       if ((LHSZero & NewMask) == (~RHSC->getAPIntValue() & NewMask)) | 
| Chris Lattner | 81cd355 | 2006-02-27 00:36:27 +0000 | [diff] [blame] | 908 |         return TLO.CombineTo(Op, Op.getOperand(0)); | 
 | 909 |       // If any of the set bits in the RHS are known zero on the LHS, shrink | 
 | 910 |       // the constant. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 911 |       if (TLO.ShrinkDemandedConstant(Op, ~LHSZero & NewMask)) | 
| Chris Lattner | 81cd355 | 2006-02-27 00:36:27 +0000 | [diff] [blame] | 912 |         return true; | 
 | 913 |     } | 
 | 914 |      | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 915 |     if (SimplifyDemandedBits(Op.getOperand(1), NewMask, KnownZero, | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 916 |                              KnownOne, TLO, Depth+1)) | 
| Chris Lattner | c6fd6cd | 2006-01-30 04:09:27 +0000 | [diff] [blame] | 917 |       return true; | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 918 |     assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");  | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 919 |     if (SimplifyDemandedBits(Op.getOperand(0), ~KnownZero & NewMask, | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 920 |                              KnownZero2, KnownOne2, TLO, Depth+1)) | 
 | 921 |       return true; | 
 | 922 |     assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");  | 
 | 923 |        | 
 | 924 |     // If all of the demanded bits are known one on one side, return the other. | 
 | 925 |     // These bits cannot contribute to the result of the 'and'. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 926 |     if ((NewMask & ~KnownZero2 & KnownOne) == (~KnownZero2 & NewMask)) | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 927 |       return TLO.CombineTo(Op, Op.getOperand(0)); | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 928 |     if ((NewMask & ~KnownZero & KnownOne2) == (~KnownZero & NewMask)) | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 929 |       return TLO.CombineTo(Op, Op.getOperand(1)); | 
 | 930 |     // If all of the demanded bits in the inputs are known zeros, return zero. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 931 |     if ((NewMask & (KnownZero|KnownZero2)) == NewMask) | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 932 |       return TLO.CombineTo(Op, TLO.DAG.getConstant(0, Op.getValueType())); | 
 | 933 |     // If the RHS is a constant, see if we can simplify it. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 934 |     if (TLO.ShrinkDemandedConstant(Op, ~KnownZero2 & NewMask)) | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 935 |       return true; | 
| Dan Gohman | 97121ba | 2009-04-08 00:15:30 +0000 | [diff] [blame] | 936 |     // If the operation can be done in a smaller type, do so. | 
 | 937 |     if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl)) | 
 | 938 |       return true; | 
 | 939 |  | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 940 |     // Output known-1 bits are only known if set in both the LHS & RHS. | 
 | 941 |     KnownOne &= KnownOne2; | 
 | 942 |     // Output known-0 are known to be clear if zero in either the LHS | RHS. | 
 | 943 |     KnownZero |= KnownZero2; | 
 | 944 |     break; | 
| Chris Lattner | c6fd6cd | 2006-01-30 04:09:27 +0000 | [diff] [blame] | 945 |   case ISD::OR: | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 946 |     if (SimplifyDemandedBits(Op.getOperand(1), NewMask, KnownZero,  | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 947 |                              KnownOne, TLO, Depth+1)) | 
 | 948 |       return true; | 
 | 949 |     assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");  | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 950 |     if (SimplifyDemandedBits(Op.getOperand(0), ~KnownOne & NewMask, | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 951 |                              KnownZero2, KnownOne2, TLO, Depth+1)) | 
 | 952 |       return true; | 
 | 953 |     assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");  | 
 | 954 |      | 
 | 955 |     // If all of the demanded bits are known zero on one side, return the other. | 
 | 956 |     // These bits cannot contribute to the result of the 'or'. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 957 |     if ((NewMask & ~KnownOne2 & KnownZero) == (~KnownOne2 & NewMask)) | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 958 |       return TLO.CombineTo(Op, Op.getOperand(0)); | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 959 |     if ((NewMask & ~KnownOne & KnownZero2) == (~KnownOne & NewMask)) | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 960 |       return TLO.CombineTo(Op, Op.getOperand(1)); | 
 | 961 |     // If all of the potentially set bits on one side are known to be set on | 
 | 962 |     // the other side, just use the 'other' side. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 963 |     if ((NewMask & ~KnownZero & KnownOne2) == (~KnownZero & NewMask)) | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 964 |       return TLO.CombineTo(Op, Op.getOperand(0)); | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 965 |     if ((NewMask & ~KnownZero2 & KnownOne) == (~KnownZero2 & NewMask)) | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 966 |       return TLO.CombineTo(Op, Op.getOperand(1)); | 
 | 967 |     // If the RHS is a constant, see if we can simplify it. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 968 |     if (TLO.ShrinkDemandedConstant(Op, NewMask)) | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 969 |       return true; | 
| Dan Gohman | 97121ba | 2009-04-08 00:15:30 +0000 | [diff] [blame] | 970 |     // If the operation can be done in a smaller type, do so. | 
 | 971 |     if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl)) | 
 | 972 |       return true; | 
 | 973 |  | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 974 |     // Output known-0 bits are only known if clear in both the LHS & RHS. | 
 | 975 |     KnownZero &= KnownZero2; | 
 | 976 |     // Output known-1 are known to be set if set in either the LHS | RHS. | 
 | 977 |     KnownOne |= KnownOne2; | 
 | 978 |     break; | 
| Chris Lattner | c6fd6cd | 2006-01-30 04:09:27 +0000 | [diff] [blame] | 979 |   case ISD::XOR: | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 980 |     if (SimplifyDemandedBits(Op.getOperand(1), NewMask, KnownZero,  | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 981 |                              KnownOne, TLO, Depth+1)) | 
 | 982 |       return true; | 
 | 983 |     assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");  | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 984 |     if (SimplifyDemandedBits(Op.getOperand(0), NewMask, KnownZero2, | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 985 |                              KnownOne2, TLO, Depth+1)) | 
 | 986 |       return true; | 
 | 987 |     assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");  | 
 | 988 |      | 
 | 989 |     // If all of the demanded bits are known zero on one side, return the other. | 
 | 990 |     // These bits cannot contribute to the result of the 'xor'. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 991 |     if ((KnownZero & NewMask) == NewMask) | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 992 |       return TLO.CombineTo(Op, Op.getOperand(0)); | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 993 |     if ((KnownZero2 & NewMask) == NewMask) | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 994 |       return TLO.CombineTo(Op, Op.getOperand(1)); | 
| Dan Gohman | 97121ba | 2009-04-08 00:15:30 +0000 | [diff] [blame] | 995 |     // If the operation can be done in a smaller type, do so. | 
 | 996 |     if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl)) | 
 | 997 |       return true; | 
 | 998 |  | 
| Chris Lattner | 3687c1a | 2006-11-27 21:50:02 +0000 | [diff] [blame] | 999 |     // If all of the unknown bits are known to be zero on one side or the other | 
 | 1000 |     // (but not both) turn this into an *inclusive* or. | 
 | 1001 |     //    e.g. (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0 | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1002 |     if ((NewMask & ~KnownZero & ~KnownZero2) == 0) | 
| Dale Johannesen | de06470 | 2009-02-06 21:50:26 +0000 | [diff] [blame] | 1003 |       return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::OR, dl, Op.getValueType(), | 
| Chris Lattner | 3687c1a | 2006-11-27 21:50:02 +0000 | [diff] [blame] | 1004 |                                                Op.getOperand(0), | 
 | 1005 |                                                Op.getOperand(1))); | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1006 |      | 
 | 1007 |     // Output known-0 bits are known if clear or set in both the LHS & RHS. | 
 | 1008 |     KnownZeroOut = (KnownZero & KnownZero2) | (KnownOne & KnownOne2); | 
 | 1009 |     // Output known-1 are known to be set if set in only one of the LHS, RHS. | 
 | 1010 |     KnownOneOut = (KnownZero & KnownOne2) | (KnownOne & KnownZero2); | 
 | 1011 |      | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1012 |     // If all of the demanded bits on one side are known, and all of the set | 
 | 1013 |     // bits on that side are also known to be set on the other side, turn this | 
 | 1014 |     // into an AND, as we know the bits will be cleared. | 
 | 1015 |     //    e.g. (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2 | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1016 |     if ((NewMask & (KnownZero|KnownOne)) == NewMask) { // all known | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1017 |       if ((KnownOne & KnownOne2) == KnownOne) { | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1018 |         MVT VT = Op.getValueType(); | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 1019 |         SDValue ANDC = TLO.DAG.getConstant(~KnownOne & NewMask, VT); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1020 |         return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::AND, dl, VT,  | 
 | 1021 |                                                  Op.getOperand(0), ANDC)); | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1022 |       } | 
 | 1023 |     } | 
 | 1024 |      | 
 | 1025 |     // If the RHS is a constant, see if we can simplify it. | 
| Torok Edwin | 4fea2e9 | 2008-04-06 21:23:02 +0000 | [diff] [blame] | 1026 |     // for XOR, we prefer to force bits to 1 if they will make a -1. | 
 | 1027 |     // if we can't force bits, try to shrink constant | 
 | 1028 |     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { | 
 | 1029 |       APInt Expanded = C->getAPIntValue() | (~NewMask); | 
 | 1030 |       // if we can expand it to have all bits set, do it | 
 | 1031 |       if (Expanded.isAllOnesValue()) { | 
 | 1032 |         if (Expanded != C->getAPIntValue()) { | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1033 |           MVT VT = Op.getValueType(); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1034 |           SDValue New = TLO.DAG.getNode(Op.getOpcode(), dl,VT, Op.getOperand(0), | 
| Torok Edwin | 4fea2e9 | 2008-04-06 21:23:02 +0000 | [diff] [blame] | 1035 |                                           TLO.DAG.getConstant(Expanded, VT)); | 
 | 1036 |           return TLO.CombineTo(Op, New); | 
 | 1037 |         } | 
 | 1038 |         // if it already has all the bits set, nothing to change | 
 | 1039 |         // but don't shrink either! | 
 | 1040 |       } else if (TLO.ShrinkDemandedConstant(Op, NewMask)) { | 
 | 1041 |         return true; | 
 | 1042 |       } | 
 | 1043 |     } | 
 | 1044 |  | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1045 |     KnownZero = KnownZeroOut; | 
 | 1046 |     KnownOne  = KnownOneOut; | 
 | 1047 |     break; | 
| Chris Lattner | c6fd6cd | 2006-01-30 04:09:27 +0000 | [diff] [blame] | 1048 |   case ISD::SELECT: | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1049 |     if (SimplifyDemandedBits(Op.getOperand(2), NewMask, KnownZero,  | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1050 |                              KnownOne, TLO, Depth+1)) | 
 | 1051 |       return true; | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1052 |     if (SimplifyDemandedBits(Op.getOperand(1), NewMask, KnownZero2, | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1053 |                              KnownOne2, TLO, Depth+1)) | 
 | 1054 |       return true; | 
 | 1055 |     assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");  | 
 | 1056 |     assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");  | 
 | 1057 |      | 
 | 1058 |     // If the operands are constants, see if we can simplify them. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1059 |     if (TLO.ShrinkDemandedConstant(Op, NewMask)) | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1060 |       return true; | 
 | 1061 |      | 
 | 1062 |     // Only known if known in both the LHS and RHS. | 
 | 1063 |     KnownOne &= KnownOne2; | 
 | 1064 |     KnownZero &= KnownZero2; | 
 | 1065 |     break; | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1066 |   case ISD::SELECT_CC: | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1067 |     if (SimplifyDemandedBits(Op.getOperand(3), NewMask, KnownZero,  | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1068 |                              KnownOne, TLO, Depth+1)) | 
 | 1069 |       return true; | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1070 |     if (SimplifyDemandedBits(Op.getOperand(2), NewMask, KnownZero2, | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1071 |                              KnownOne2, TLO, Depth+1)) | 
 | 1072 |       return true; | 
 | 1073 |     assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");  | 
 | 1074 |     assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");  | 
 | 1075 |      | 
 | 1076 |     // If the operands are constants, see if we can simplify them. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1077 |     if (TLO.ShrinkDemandedConstant(Op, NewMask)) | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1078 |       return true; | 
 | 1079 |        | 
 | 1080 |     // Only known if known in both the LHS and RHS. | 
 | 1081 |     KnownOne &= KnownOne2; | 
 | 1082 |     KnownZero &= KnownZero2; | 
 | 1083 |     break; | 
| Chris Lattner | c6fd6cd | 2006-01-30 04:09:27 +0000 | [diff] [blame] | 1084 |   case ISD::SHL: | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1085 |     if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 1086 |       unsigned ShAmt = SA->getZExtValue(); | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 1087 |       SDValue InOp = Op.getOperand(0); | 
| Chris Lattner | 895c4ab | 2007-04-17 21:14:16 +0000 | [diff] [blame] | 1088 |  | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1089 |       // If the shift count is an invalid immediate, don't do anything. | 
 | 1090 |       if (ShAmt >= BitWidth) | 
 | 1091 |         break; | 
 | 1092 |  | 
| Chris Lattner | 895c4ab | 2007-04-17 21:14:16 +0000 | [diff] [blame] | 1093 |       // If this is ((X >>u C1) << ShAmt), see if we can simplify this into a | 
 | 1094 |       // single shift.  We can do this if the bottom bits (which are shifted | 
 | 1095 |       // out) are never demanded. | 
 | 1096 |       if (InOp.getOpcode() == ISD::SRL && | 
 | 1097 |           isa<ConstantSDNode>(InOp.getOperand(1))) { | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1098 |         if (ShAmt && (NewMask & APInt::getLowBitsSet(BitWidth, ShAmt)) == 0) { | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 1099 |           unsigned C1= cast<ConstantSDNode>(InOp.getOperand(1))->getZExtValue(); | 
| Chris Lattner | 895c4ab | 2007-04-17 21:14:16 +0000 | [diff] [blame] | 1100 |           unsigned Opc = ISD::SHL; | 
 | 1101 |           int Diff = ShAmt-C1; | 
 | 1102 |           if (Diff < 0) { | 
 | 1103 |             Diff = -Diff; | 
 | 1104 |             Opc = ISD::SRL; | 
 | 1105 |           }           | 
 | 1106 |            | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 1107 |           SDValue NewSA =  | 
| Chris Lattner | 4e7e6cd | 2007-05-30 16:30:06 +0000 | [diff] [blame] | 1108 |             TLO.DAG.getConstant(Diff, Op.getOperand(1).getValueType()); | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1109 |           MVT VT = Op.getValueType(); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1110 |           return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, dl, VT, | 
| Chris Lattner | 895c4ab | 2007-04-17 21:14:16 +0000 | [diff] [blame] | 1111 |                                                    InOp.getOperand(0), NewSA)); | 
 | 1112 |         } | 
 | 1113 |       }       | 
 | 1114 |        | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1115 |       if (SimplifyDemandedBits(Op.getOperand(0), NewMask.lshr(ShAmt), | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1116 |                                KnownZero, KnownOne, TLO, Depth+1)) | 
| Chris Lattner | c6fd6cd | 2006-01-30 04:09:27 +0000 | [diff] [blame] | 1117 |         return true; | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 1118 |       KnownZero <<= SA->getZExtValue(); | 
 | 1119 |       KnownOne  <<= SA->getZExtValue(); | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1120 |       // low bits known zero. | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 1121 |       KnownZero |= APInt::getLowBitsSet(BitWidth, SA->getZExtValue()); | 
| Chris Lattner | c6fd6cd | 2006-01-30 04:09:27 +0000 | [diff] [blame] | 1122 |     } | 
 | 1123 |     break; | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1124 |   case ISD::SRL: | 
 | 1125 |     if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1126 |       MVT VT = Op.getValueType(); | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 1127 |       unsigned ShAmt = SA->getZExtValue(); | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1128 |       unsigned VTSize = VT.getSizeInBits(); | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 1129 |       SDValue InOp = Op.getOperand(0); | 
| Chris Lattner | 895c4ab | 2007-04-17 21:14:16 +0000 | [diff] [blame] | 1130 |        | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1131 |       // If the shift count is an invalid immediate, don't do anything. | 
 | 1132 |       if (ShAmt >= BitWidth) | 
 | 1133 |         break; | 
 | 1134 |  | 
| Chris Lattner | 895c4ab | 2007-04-17 21:14:16 +0000 | [diff] [blame] | 1135 |       // If this is ((X << C1) >>u ShAmt), see if we can simplify this into a | 
 | 1136 |       // single shift.  We can do this if the top bits (which are shifted out) | 
 | 1137 |       // are never demanded. | 
 | 1138 |       if (InOp.getOpcode() == ISD::SHL && | 
 | 1139 |           isa<ConstantSDNode>(InOp.getOperand(1))) { | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1140 |         if (ShAmt && (NewMask & APInt::getHighBitsSet(VTSize, ShAmt)) == 0) { | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 1141 |           unsigned C1= cast<ConstantSDNode>(InOp.getOperand(1))->getZExtValue(); | 
| Chris Lattner | 895c4ab | 2007-04-17 21:14:16 +0000 | [diff] [blame] | 1142 |           unsigned Opc = ISD::SRL; | 
 | 1143 |           int Diff = ShAmt-C1; | 
 | 1144 |           if (Diff < 0) { | 
 | 1145 |             Diff = -Diff; | 
 | 1146 |             Opc = ISD::SHL; | 
 | 1147 |           }           | 
 | 1148 |            | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 1149 |           SDValue NewSA = | 
| Chris Lattner | 8c7d2d5 | 2007-04-17 22:53:02 +0000 | [diff] [blame] | 1150 |             TLO.DAG.getConstant(Diff, Op.getOperand(1).getValueType()); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1151 |           return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, dl, VT, | 
| Chris Lattner | 895c4ab | 2007-04-17 21:14:16 +0000 | [diff] [blame] | 1152 |                                                    InOp.getOperand(0), NewSA)); | 
 | 1153 |         } | 
 | 1154 |       }       | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1155 |        | 
 | 1156 |       // Compute the new bits that are at the top now. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1157 |       if (SimplifyDemandedBits(InOp, (NewMask << ShAmt), | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1158 |                                KnownZero, KnownOne, TLO, Depth+1)) | 
 | 1159 |         return true; | 
 | 1160 |       assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");  | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1161 |       KnownZero = KnownZero.lshr(ShAmt); | 
 | 1162 |       KnownOne  = KnownOne.lshr(ShAmt); | 
| Chris Lattner | c4fa603 | 2006-06-13 16:52:37 +0000 | [diff] [blame] | 1163 |  | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1164 |       APInt HighBits = APInt::getHighBitsSet(BitWidth, ShAmt); | 
| Chris Lattner | c4fa603 | 2006-06-13 16:52:37 +0000 | [diff] [blame] | 1165 |       KnownZero |= HighBits;  // High bits known zero. | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1166 |     } | 
 | 1167 |     break; | 
 | 1168 |   case ISD::SRA: | 
| Dan Gohman | e5af2d3 | 2009-01-29 01:59:02 +0000 | [diff] [blame] | 1169 |     // If this is an arithmetic shift right and only the low-bit is set, we can | 
 | 1170 |     // always convert this into a logical shr, even if the shift amount is | 
 | 1171 |     // variable.  The low bit of the shift cannot be an input sign bit unless | 
 | 1172 |     // the shift amount is >= the size of the datatype, which is undefined. | 
 | 1173 |     if (DemandedMask == 1) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1174 |       return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, Op.getValueType(), | 
| Dan Gohman | e5af2d3 | 2009-01-29 01:59:02 +0000 | [diff] [blame] | 1175 |                                                Op.getOperand(0), Op.getOperand(1))); | 
 | 1176 |  | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1177 |     if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1178 |       MVT VT = Op.getValueType(); | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 1179 |       unsigned ShAmt = SA->getZExtValue(); | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1180 |        | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1181 |       // If the shift count is an invalid immediate, don't do anything. | 
 | 1182 |       if (ShAmt >= BitWidth) | 
 | 1183 |         break; | 
 | 1184 |  | 
 | 1185 |       APInt InDemandedMask = (NewMask << ShAmt); | 
| Chris Lattner | 1b73713 | 2006-05-08 17:22:53 +0000 | [diff] [blame] | 1186 |  | 
 | 1187 |       // If any of the demanded bits are produced by the sign extension, we also | 
 | 1188 |       // demand the input sign bit. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1189 |       APInt HighBits = APInt::getHighBitsSet(BitWidth, ShAmt); | 
 | 1190 |       if (HighBits.intersects(NewMask)) | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1191 |         InDemandedMask |= APInt::getSignBit(VT.getSizeInBits()); | 
| Chris Lattner | 1b73713 | 2006-05-08 17:22:53 +0000 | [diff] [blame] | 1192 |        | 
 | 1193 |       if (SimplifyDemandedBits(Op.getOperand(0), InDemandedMask, | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1194 |                                KnownZero, KnownOne, TLO, Depth+1)) | 
 | 1195 |         return true; | 
 | 1196 |       assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");  | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1197 |       KnownZero = KnownZero.lshr(ShAmt); | 
 | 1198 |       KnownOne  = KnownOne.lshr(ShAmt); | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1199 |        | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1200 |       // Handle the sign bit, adjusted to where it is now in the mask. | 
 | 1201 |       APInt SignBit = APInt::getSignBit(BitWidth).lshr(ShAmt); | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1202 |        | 
 | 1203 |       // If the input sign bit is known to be zero, or if none of the top bits | 
 | 1204 |       // are demanded, turn this into an unsigned shift right. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1205 |       if (KnownZero.intersects(SignBit) || (HighBits & ~NewMask) == HighBits) { | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1206 |         return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, VT,  | 
 | 1207 |                                                  Op.getOperand(0), | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1208 |                                                  Op.getOperand(1))); | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1209 |       } else if (KnownOne.intersects(SignBit)) { // New bits are known one. | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1210 |         KnownOne |= HighBits; | 
 | 1211 |       } | 
 | 1212 |     } | 
 | 1213 |     break; | 
 | 1214 |   case ISD::SIGN_EXTEND_INREG: { | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1215 |     MVT EVT = cast<VTSDNode>(Op.getOperand(1))->getVT(); | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1216 |  | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1217 |     // Sign extension.  Compute the demanded bits in the result that are not  | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1218 |     // present in the input. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1219 |     APInt NewBits = APInt::getHighBitsSet(BitWidth, | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1220 |                                           BitWidth - EVT.getSizeInBits()) & | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1221 |                     NewMask; | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1222 |      | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1223 |     // If none of the extended bits are demanded, eliminate the sextinreg. | 
 | 1224 |     if (NewBits == 0) | 
 | 1225 |       return TLO.CombineTo(Op, Op.getOperand(0)); | 
 | 1226 |  | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1227 |     APInt InSignBit = APInt::getSignBit(EVT.getSizeInBits()); | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1228 |     InSignBit.zext(BitWidth); | 
 | 1229 |     APInt InputDemandedBits = APInt::getLowBitsSet(BitWidth, | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1230 |                                                    EVT.getSizeInBits()) & | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1231 |                               NewMask; | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1232 |      | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1233 |     // Since the sign extended bits are demanded, we know that the sign | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1234 |     // bit is demanded. | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1235 |     InputDemandedBits |= InSignBit; | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1236 |  | 
 | 1237 |     if (SimplifyDemandedBits(Op.getOperand(0), InputDemandedBits, | 
 | 1238 |                              KnownZero, KnownOne, TLO, Depth+1)) | 
 | 1239 |       return true; | 
 | 1240 |     assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");  | 
 | 1241 |  | 
 | 1242 |     // If the sign bit of the input is known set or clear, then we know the | 
 | 1243 |     // top bits of the result. | 
 | 1244 |      | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1245 |     // If the input sign bit is known zero, convert this into a zero extension. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1246 |     if (KnownZero.intersects(InSignBit)) | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1247 |       return TLO.CombineTo(Op,  | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1248 |                            TLO.DAG.getZeroExtendInReg(Op.getOperand(0),dl,EVT)); | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1249 |      | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1250 |     if (KnownOne.intersects(InSignBit)) {    // Input sign bit known set | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1251 |       KnownOne |= NewBits; | 
 | 1252 |       KnownZero &= ~NewBits; | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1253 |     } else {                       // Input sign bit unknown | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1254 |       KnownZero &= ~NewBits; | 
 | 1255 |       KnownOne &= ~NewBits; | 
 | 1256 |     } | 
 | 1257 |     break; | 
 | 1258 |   } | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1259 |   case ISD::ZERO_EXTEND: { | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1260 |     unsigned OperandBitWidth = Op.getOperand(0).getValueSizeInBits(); | 
 | 1261 |     APInt InMask = NewMask; | 
 | 1262 |     InMask.trunc(OperandBitWidth); | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1263 |      | 
 | 1264 |     // If none of the top bits are demanded, convert this into an any_extend. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1265 |     APInt NewBits = | 
 | 1266 |       APInt::getHighBitsSet(BitWidth, BitWidth - OperandBitWidth) & NewMask; | 
 | 1267 |     if (!NewBits.intersects(NewMask)) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1268 |       return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ANY_EXTEND, dl, | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1269 |                                                Op.getValueType(),  | 
 | 1270 |                                                Op.getOperand(0))); | 
 | 1271 |      | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1272 |     if (SimplifyDemandedBits(Op.getOperand(0), InMask, | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1273 |                              KnownZero, KnownOne, TLO, Depth+1)) | 
 | 1274 |       return true; | 
 | 1275 |     assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");  | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1276 |     KnownZero.zext(BitWidth); | 
 | 1277 |     KnownOne.zext(BitWidth); | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1278 |     KnownZero |= NewBits; | 
 | 1279 |     break; | 
 | 1280 |   } | 
 | 1281 |   case ISD::SIGN_EXTEND: { | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1282 |     MVT InVT = Op.getOperand(0).getValueType(); | 
 | 1283 |     unsigned InBits = InVT.getSizeInBits(); | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1284 |     APInt InMask    = APInt::getLowBitsSet(BitWidth, InBits); | 
| Dan Gohman | 9736028 | 2008-03-11 21:29:43 +0000 | [diff] [blame] | 1285 |     APInt InSignBit = APInt::getBitsSet(BitWidth, InBits - 1, InBits); | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1286 |     APInt NewBits   = ~InMask & NewMask; | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1287 |      | 
 | 1288 |     // If none of the top bits are demanded, convert this into an any_extend. | 
 | 1289 |     if (NewBits == 0) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1290 |       return TLO.CombineTo(Op,TLO.DAG.getNode(ISD::ANY_EXTEND, dl, | 
 | 1291 |                                               Op.getValueType(), | 
 | 1292 |                                               Op.getOperand(0))); | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1293 |      | 
 | 1294 |     // Since some of the sign extended bits are demanded, we know that the sign | 
 | 1295 |     // bit is demanded. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1296 |     APInt InDemandedBits = InMask & NewMask; | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1297 |     InDemandedBits |= InSignBit; | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1298 |     InDemandedBits.trunc(InBits); | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1299 |      | 
 | 1300 |     if (SimplifyDemandedBits(Op.getOperand(0), InDemandedBits, KnownZero,  | 
 | 1301 |                              KnownOne, TLO, Depth+1)) | 
 | 1302 |       return true; | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1303 |     KnownZero.zext(BitWidth); | 
 | 1304 |     KnownOne.zext(BitWidth); | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1305 |      | 
 | 1306 |     // If the sign bit is known zero, convert this to a zero extend. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1307 |     if (KnownZero.intersects(InSignBit)) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1308 |       return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ZERO_EXTEND, dl, | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1309 |                                                Op.getValueType(),  | 
 | 1310 |                                                Op.getOperand(0))); | 
 | 1311 |      | 
 | 1312 |     // If the sign bit is known one, the top bits match. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1313 |     if (KnownOne.intersects(InSignBit)) { | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1314 |       KnownOne  |= NewBits; | 
 | 1315 |       KnownZero &= ~NewBits; | 
 | 1316 |     } else {   // Otherwise, top bits aren't known. | 
 | 1317 |       KnownOne  &= ~NewBits; | 
 | 1318 |       KnownZero &= ~NewBits; | 
 | 1319 |     } | 
 | 1320 |     break; | 
 | 1321 |   } | 
 | 1322 |   case ISD::ANY_EXTEND: { | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1323 |     unsigned OperandBitWidth = Op.getOperand(0).getValueSizeInBits(); | 
 | 1324 |     APInt InMask = NewMask; | 
 | 1325 |     InMask.trunc(OperandBitWidth); | 
 | 1326 |     if (SimplifyDemandedBits(Op.getOperand(0), InMask, | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1327 |                              KnownZero, KnownOne, TLO, Depth+1)) | 
 | 1328 |       return true; | 
 | 1329 |     assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");  | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1330 |     KnownZero.zext(BitWidth); | 
 | 1331 |     KnownOne.zext(BitWidth); | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1332 |     break; | 
 | 1333 |   } | 
| Chris Lattner | fe8babf | 2006-05-05 22:32:12 +0000 | [diff] [blame] | 1334 |   case ISD::TRUNCATE: { | 
| Chris Lattner | c93dfda | 2006-05-06 00:11:52 +0000 | [diff] [blame] | 1335 |     // Simplify the input, using demanded bit information, and compute the known | 
 | 1336 |     // zero/one bits live out. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1337 |     APInt TruncMask = NewMask; | 
 | 1338 |     TruncMask.zext(Op.getOperand(0).getValueSizeInBits()); | 
 | 1339 |     if (SimplifyDemandedBits(Op.getOperand(0), TruncMask, | 
| Chris Lattner | fe8babf | 2006-05-05 22:32:12 +0000 | [diff] [blame] | 1340 |                              KnownZero, KnownOne, TLO, Depth+1)) | 
 | 1341 |       return true; | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1342 |     KnownZero.trunc(BitWidth); | 
 | 1343 |     KnownOne.trunc(BitWidth); | 
| Chris Lattner | c93dfda | 2006-05-06 00:11:52 +0000 | [diff] [blame] | 1344 |      | 
 | 1345 |     // If the input is only used by this truncate, see if we can shrink it based | 
 | 1346 |     // on the known demanded bits. | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 1347 |     if (Op.getOperand(0).getNode()->hasOneUse()) { | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 1348 |       SDValue In = Op.getOperand(0); | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1349 |       unsigned InBitWidth = In.getValueSizeInBits(); | 
| Chris Lattner | c93dfda | 2006-05-06 00:11:52 +0000 | [diff] [blame] | 1350 |       switch (In.getOpcode()) { | 
 | 1351 |       default: break; | 
 | 1352 |       case ISD::SRL: | 
 | 1353 |         // Shrink SRL by a constant if none of the high bits shifted in are | 
 | 1354 |         // demanded. | 
 | 1355 |         if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(In.getOperand(1))){ | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1356 |           APInt HighBits = APInt::getHighBitsSet(InBitWidth, | 
 | 1357 |                                                  InBitWidth - BitWidth); | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 1358 |           HighBits = HighBits.lshr(ShAmt->getZExtValue()); | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1359 |           HighBits.trunc(BitWidth); | 
| Chris Lattner | c93dfda | 2006-05-06 00:11:52 +0000 | [diff] [blame] | 1360 |            | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 1361 |           if (ShAmt->getZExtValue() < BitWidth && !(HighBits & NewMask)) { | 
| Chris Lattner | c93dfda | 2006-05-06 00:11:52 +0000 | [diff] [blame] | 1362 |             // None of the shifted in bits are needed.  Add a truncate of the | 
 | 1363 |             // shift input, then shift it. | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1364 |             SDValue NewTrunc = TLO.DAG.getNode(ISD::TRUNCATE, dl, | 
| Chris Lattner | c93dfda | 2006-05-06 00:11:52 +0000 | [diff] [blame] | 1365 |                                                  Op.getValueType(),  | 
 | 1366 |                                                  In.getOperand(0)); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1367 |             return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, | 
 | 1368 |                                                      Op.getValueType(), | 
 | 1369 |                                                      NewTrunc,  | 
 | 1370 |                                                      In.getOperand(1))); | 
| Chris Lattner | c93dfda | 2006-05-06 00:11:52 +0000 | [diff] [blame] | 1371 |           } | 
 | 1372 |         } | 
 | 1373 |         break; | 
 | 1374 |       } | 
 | 1375 |     } | 
 | 1376 |      | 
| Chris Lattner | fe8babf | 2006-05-05 22:32:12 +0000 | [diff] [blame] | 1377 |     assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");  | 
| Chris Lattner | fe8babf | 2006-05-05 22:32:12 +0000 | [diff] [blame] | 1378 |     break; | 
 | 1379 |   } | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1380 |   case ISD::AssertZext: { | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1381 |     MVT VT = cast<VTSDNode>(Op.getOperand(1))->getVT(); | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1382 |     APInt InMask = APInt::getLowBitsSet(BitWidth, | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1383 |                                         VT.getSizeInBits()); | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1384 |     if (SimplifyDemandedBits(Op.getOperand(0), InMask & NewMask, | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1385 |                              KnownZero, KnownOne, TLO, Depth+1)) | 
 | 1386 |       return true; | 
 | 1387 |     assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");  | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1388 |     KnownZero |= ~InMask & NewMask; | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1389 |     break; | 
 | 1390 |   } | 
| Chris Lattner | 2ceb2cf | 2007-12-22 21:35:38 +0000 | [diff] [blame] | 1391 |   case ISD::BIT_CONVERT: | 
 | 1392 | #if 0 | 
 | 1393 |     // If this is an FP->Int bitcast and if the sign bit is the only thing that | 
 | 1394 |     // is demanded, turn this into a FGETSIGN. | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1395 |     if (NewMask == MVT::getIntegerVTSignBit(Op.getValueType()) && | 
| Chris Lattner | 2ceb2cf | 2007-12-22 21:35:38 +0000 | [diff] [blame] | 1396 |         MVT::isFloatingPoint(Op.getOperand(0).getValueType()) && | 
 | 1397 |         !MVT::isVector(Op.getOperand(0).getValueType())) { | 
 | 1398 |       // Only do this xform if FGETSIGN is valid or if before legalize. | 
 | 1399 |       if (!TLO.AfterLegalize || | 
 | 1400 |           isOperationLegal(ISD::FGETSIGN, Op.getValueType())) { | 
 | 1401 |         // Make a FGETSIGN + SHL to move the sign bit into the appropriate | 
 | 1402 |         // place.  We expect the SHL to be eliminated by other optimizations. | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 1403 |         SDValue Sign = TLO.DAG.getNode(ISD::FGETSIGN, Op.getValueType(),  | 
| Chris Lattner | 2ceb2cf | 2007-12-22 21:35:38 +0000 | [diff] [blame] | 1404 |                                          Op.getOperand(0)); | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1405 |         unsigned ShVal = Op.getValueType().getSizeInBits()-1; | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 1406 |         SDValue ShAmt = TLO.DAG.getConstant(ShVal, getShiftAmountTy()); | 
| Chris Lattner | 2ceb2cf | 2007-12-22 21:35:38 +0000 | [diff] [blame] | 1407 |         return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SHL, Op.getValueType(), | 
 | 1408 |                                                  Sign, ShAmt)); | 
 | 1409 |       } | 
 | 1410 |     } | 
 | 1411 | #endif | 
 | 1412 |     break; | 
| Dan Gohman | 97121ba | 2009-04-08 00:15:30 +0000 | [diff] [blame] | 1413 |   case ISD::ADD: | 
 | 1414 |   case ISD::MUL: | 
 | 1415 |   case ISD::SUB: { | 
 | 1416 |     // Add, Sub, and Mul don't demand any bits in positions beyond that | 
 | 1417 |     // of the highest bit demanded of them. | 
 | 1418 |     APInt LoMask = APInt::getLowBitsSet(BitWidth, | 
 | 1419 |                                         BitWidth - NewMask.countLeadingZeros()); | 
 | 1420 |     if (SimplifyDemandedBits(Op.getOperand(0), LoMask, KnownZero2, | 
 | 1421 |                              KnownOne2, TLO, Depth+1)) | 
 | 1422 |       return true; | 
 | 1423 |     if (SimplifyDemandedBits(Op.getOperand(1), LoMask, KnownZero2, | 
 | 1424 |                              KnownOne2, TLO, Depth+1)) | 
 | 1425 |       return true; | 
 | 1426 |     // See if the operation should be performed at a smaller bit width. | 
 | 1427 |     if (TLO.ShrinkDemandedOp(Op, BitWidth, NewMask, dl)) | 
 | 1428 |       return true; | 
 | 1429 |   } | 
 | 1430 |   // FALL THROUGH | 
| Dan Gohman | 54eed37 | 2008-05-06 00:53:29 +0000 | [diff] [blame] | 1431 |   default: | 
| Chris Lattner | 1482b5f | 2006-04-02 06:15:09 +0000 | [diff] [blame] | 1432 |     // Just use ComputeMaskedBits to compute output bits. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1433 |     TLO.DAG.ComputeMaskedBits(Op, NewMask, KnownZero, KnownOne, Depth); | 
| Chris Lattner | a6bc5a4 | 2006-02-27 01:00:42 +0000 | [diff] [blame] | 1434 |     break; | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1435 |   } | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1436 |    | 
 | 1437 |   // If we know the value of all of the demanded bits, return this as a | 
 | 1438 |   // constant. | 
| Dan Gohman | 7b8d4a9 | 2008-02-27 00:25:32 +0000 | [diff] [blame] | 1439 |   if ((NewMask & (KnownZero|KnownOne)) == NewMask) | 
| Chris Lattner | ec66515 | 2006-02-26 23:36:02 +0000 | [diff] [blame] | 1440 |     return TLO.CombineTo(Op, TLO.DAG.getConstant(KnownOne, Op.getValueType())); | 
 | 1441 |    | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1442 |   return false; | 
 | 1443 | } | 
 | 1444 |  | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1445 | /// computeMaskedBitsForTargetNode - Determine which of the bits specified  | 
 | 1446 | /// in Mask are known to be either zero or one and return them in the  | 
 | 1447 | /// KnownZero/KnownOne bitsets. | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 1448 | void TargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,  | 
| Dan Gohman | 977a76f | 2008-02-13 22:28:48 +0000 | [diff] [blame] | 1449 |                                                     const APInt &Mask, | 
| Dan Gohman | fd29e0e | 2008-02-13 00:35:47 +0000 | [diff] [blame] | 1450 |                                                     APInt &KnownZero,  | 
 | 1451 |                                                     APInt &KnownOne, | 
| Dan Gohman | ea859be | 2007-06-22 14:59:07 +0000 | [diff] [blame] | 1452 |                                                     const SelectionDAG &DAG, | 
| Nate Begeman | 368e18d | 2006-02-16 21:11:51 +0000 | [diff] [blame] | 1453 |                                                     unsigned Depth) const { | 
| Chris Lattner | 1b5232a | 2006-04-02 06:19:46 +0000 | [diff] [blame] | 1454 |   assert((Op.getOpcode() >= ISD::BUILTIN_OP_END || | 
 | 1455 |           Op.getOpcode() == ISD::INTRINSIC_WO_CHAIN || | 
 | 1456 |           Op.getOpcode() == ISD::INTRINSIC_W_CHAIN || | 
 | 1457 |           Op.getOpcode() == ISD::INTRINSIC_VOID) && | 
| Chris Lattner | c6fd6cd | 2006-01-30 04:09:27 +0000 | [diff] [blame] | 1458 |          "Should use MaskedValueIsZero if you don't know whether Op" | 
 | 1459 |          " is a target node!"); | 
| Dan Gohman | 977a76f | 2008-02-13 22:28:48 +0000 | [diff] [blame] | 1460 |   KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0); | 
| Evan Cheng | 3a03ebb | 2005-12-21 23:05:39 +0000 | [diff] [blame] | 1461 | } | 
| Chris Lattner | 4ccb070 | 2006-01-26 20:37:03 +0000 | [diff] [blame] | 1462 |  | 
| Chris Lattner | 5c3e21d | 2006-05-06 09:27:13 +0000 | [diff] [blame] | 1463 | /// ComputeNumSignBitsForTargetNode - This method can be implemented by | 
 | 1464 | /// targets that want to expose additional information about sign bits to the | 
 | 1465 | /// DAG Combiner. | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 1466 | unsigned TargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op, | 
| Chris Lattner | 5c3e21d | 2006-05-06 09:27:13 +0000 | [diff] [blame] | 1467 |                                                          unsigned Depth) const { | 
 | 1468 |   assert((Op.getOpcode() >= ISD::BUILTIN_OP_END || | 
 | 1469 |           Op.getOpcode() == ISD::INTRINSIC_WO_CHAIN || | 
 | 1470 |           Op.getOpcode() == ISD::INTRINSIC_W_CHAIN || | 
 | 1471 |           Op.getOpcode() == ISD::INTRINSIC_VOID) && | 
 | 1472 |          "Should use ComputeNumSignBits if you don't know whether Op" | 
 | 1473 |          " is a target node!"); | 
 | 1474 |   return 1; | 
 | 1475 | } | 
 | 1476 |  | 
| Dan Gohman | 97d1163 | 2009-02-15 23:59:32 +0000 | [diff] [blame] | 1477 | /// ValueHasExactlyOneBitSet - Test if the given value is known to have exactly | 
 | 1478 | /// one bit set. This differs from ComputeMaskedBits in that it doesn't need to | 
 | 1479 | /// determine which bit is set. | 
 | 1480 | /// | 
| Dale Johannesen | 85b0ede | 2009-02-11 19:19:41 +0000 | [diff] [blame] | 1481 | static bool ValueHasExactlyOneBitSet(SDValue Val, const SelectionDAG &DAG) { | 
| Dan Gohman | 97d1163 | 2009-02-15 23:59:32 +0000 | [diff] [blame] | 1482 |   // A left-shift of a constant one will have exactly one bit set, because | 
 | 1483 |   // shifting the bit off the end is undefined. | 
 | 1484 |   if (Val.getOpcode() == ISD::SHL) | 
 | 1485 |     if (ConstantSDNode *C = | 
 | 1486 |          dyn_cast<ConstantSDNode>(Val.getNode()->getOperand(0))) | 
 | 1487 |       if (C->getAPIntValue() == 1) | 
 | 1488 |         return true; | 
| Dan Gohman | e5af2d3 | 2009-01-29 01:59:02 +0000 | [diff] [blame] | 1489 |  | 
| Dan Gohman | 97d1163 | 2009-02-15 23:59:32 +0000 | [diff] [blame] | 1490 |   // Similarly, a right-shift of a constant sign-bit will have exactly | 
 | 1491 |   // one bit set. | 
 | 1492 |   if (Val.getOpcode() == ISD::SRL) | 
 | 1493 |     if (ConstantSDNode *C = | 
 | 1494 |          dyn_cast<ConstantSDNode>(Val.getNode()->getOperand(0))) | 
 | 1495 |       if (C->getAPIntValue().isSignBit()) | 
 | 1496 |         return true; | 
 | 1497 |  | 
 | 1498 |   // More could be done here, though the above checks are enough | 
 | 1499 |   // to handle some common cases. | 
 | 1500 |  | 
 | 1501 |   // Fall back to ComputeMaskedBits to catch other known cases. | 
| Dan Gohman | e5af2d3 | 2009-01-29 01:59:02 +0000 | [diff] [blame] | 1502 |   MVT OpVT = Val.getValueType(); | 
 | 1503 |   unsigned BitWidth = OpVT.getSizeInBits(); | 
 | 1504 |   APInt Mask = APInt::getAllOnesValue(BitWidth); | 
 | 1505 |   APInt KnownZero, KnownOne; | 
 | 1506 |   DAG.ComputeMaskedBits(Val, Mask, KnownZero, KnownOne); | 
| Dale Johannesen | 85b0ede | 2009-02-11 19:19:41 +0000 | [diff] [blame] | 1507 |   return (KnownZero.countPopulation() == BitWidth - 1) && | 
 | 1508 |          (KnownOne.countPopulation() == 1); | 
| Dan Gohman | e5af2d3 | 2009-01-29 01:59:02 +0000 | [diff] [blame] | 1509 | } | 
| Chris Lattner | 5c3e21d | 2006-05-06 09:27:13 +0000 | [diff] [blame] | 1510 |  | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1511 | /// SimplifySetCC - Try to simplify a setcc built with the specified operands  | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 1512 | /// and cc. If it is unable to simplify it, return a null SDValue. | 
 | 1513 | SDValue | 
 | 1514 | TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1515 |                               ISD::CondCode Cond, bool foldBooleans, | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1516 |                               DAGCombinerInfo &DCI, DebugLoc dl) const { | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1517 |   SelectionDAG &DAG = DCI.DAG; | 
 | 1518 |  | 
 | 1519 |   // These setcc operations always fold. | 
 | 1520 |   switch (Cond) { | 
 | 1521 |   default: break; | 
 | 1522 |   case ISD::SETFALSE: | 
 | 1523 |   case ISD::SETFALSE2: return DAG.getConstant(0, VT); | 
 | 1524 |   case ISD::SETTRUE: | 
 | 1525 |   case ISD::SETTRUE2:  return DAG.getConstant(1, VT); | 
 | 1526 |   } | 
 | 1527 |  | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1528 |   if (isa<ConstantSDNode>(N0.getNode())) { | 
 | 1529 |     // Ensure that the constant occurs on the RHS, and fold constant | 
 | 1530 |     // comparisons. | 
 | 1531 |     return DAG.getSetCC(dl, VT, N1, N0, ISD::getSetCCSwappedOperands(Cond)); | 
 | 1532 |   } | 
 | 1533 |  | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 1534 |   if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getNode())) { | 
| Dan Gohman | 6c6cd1c | 2008-03-03 22:22:56 +0000 | [diff] [blame] | 1535 |     const APInt &C1 = N1C->getAPIntValue(); | 
| Dale Johannesen | 89217a6 | 2008-11-07 01:28:02 +0000 | [diff] [blame] | 1536 |  | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1537 |     // If the LHS is '(srl (ctlz x), 5)', the RHS is 0/1, and this is an | 
 | 1538 |     // equality comparison, then we're just comparing whether X itself is | 
 | 1539 |     // zero. | 
 | 1540 |     if (N0.getOpcode() == ISD::SRL && (C1 == 0 || C1 == 1) && | 
 | 1541 |         N0.getOperand(0).getOpcode() == ISD::CTLZ && | 
 | 1542 |         N0.getOperand(1).getOpcode() == ISD::Constant) { | 
 | 1543 |       unsigned ShAmt = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue(); | 
 | 1544 |       if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) && | 
 | 1545 |           ShAmt == Log2_32(N0.getValueType().getSizeInBits())) { | 
 | 1546 |         if ((C1 == 0) == (Cond == ISD::SETEQ)) { | 
 | 1547 |           // (srl (ctlz x), 5) == 0  -> X != 0 | 
 | 1548 |           // (srl (ctlz x), 5) != 1  -> X != 0 | 
 | 1549 |           Cond = ISD::SETNE; | 
 | 1550 |         } else { | 
 | 1551 |           // (srl (ctlz x), 5) != 0  -> X == 0 | 
 | 1552 |           // (srl (ctlz x), 5) == 1  -> X == 0 | 
 | 1553 |           Cond = ISD::SETEQ; | 
 | 1554 |         } | 
 | 1555 |         SDValue Zero = DAG.getConstant(0, N0.getValueType()); | 
 | 1556 |         return DAG.getSetCC(dl, VT, N0.getOperand(0).getOperand(0), | 
 | 1557 |                             Zero, Cond); | 
 | 1558 |       } | 
 | 1559 |     } | 
 | 1560 |  | 
 | 1561 |     // If the LHS is '(and load, const)', the RHS is 0, | 
 | 1562 |     // the test is for equality or unsigned, and all 1 bits of the const are | 
 | 1563 |     // in the same partial word, see if we can shorten the load. | 
 | 1564 |     if (DCI.isBeforeLegalize() && | 
 | 1565 |         N0.getOpcode() == ISD::AND && C1 == 0 && | 
 | 1566 |         N0.getNode()->hasOneUse() && | 
 | 1567 |         isa<LoadSDNode>(N0.getOperand(0)) && | 
 | 1568 |         N0.getOperand(0).getNode()->hasOneUse() && | 
 | 1569 |         isa<ConstantSDNode>(N0.getOperand(1))) { | 
 | 1570 |       LoadSDNode *Lod = cast<LoadSDNode>(N0.getOperand(0)); | 
 | 1571 |       uint64_t bestMask = 0; | 
 | 1572 |       unsigned bestWidth = 0, bestOffset = 0; | 
 | 1573 |       if (!Lod->isVolatile() && Lod->isUnindexed() && | 
 | 1574 |           // FIXME: This uses getZExtValue() below so it only works on i64 and | 
 | 1575 |           // below. | 
 | 1576 |           N0.getValueType().getSizeInBits() <= 64) { | 
 | 1577 |         unsigned origWidth = N0.getValueType().getSizeInBits(); | 
 | 1578 |         // We can narrow (e.g.) 16-bit extending loads on 32-bit target to  | 
 | 1579 |         // 8 bits, but have to be careful... | 
 | 1580 |         if (Lod->getExtensionType() != ISD::NON_EXTLOAD) | 
 | 1581 |           origWidth = Lod->getMemoryVT().getSizeInBits(); | 
 | 1582 |         uint64_t Mask =cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue(); | 
 | 1583 |         for (unsigned width = origWidth / 2; width>=8; width /= 2) { | 
 | 1584 |           uint64_t newMask = (1ULL << width) - 1; | 
 | 1585 |           for (unsigned offset=0; offset<origWidth/width; offset++) { | 
 | 1586 |             if ((newMask & Mask) == Mask) { | 
 | 1587 |               if (!TD->isLittleEndian()) | 
 | 1588 |                 bestOffset = (origWidth/width - offset - 1) * (width/8); | 
 | 1589 |               else | 
 | 1590 |                 bestOffset = (uint64_t)offset * (width/8); | 
 | 1591 |               bestMask = Mask >> (offset * (width/8) * 8); | 
 | 1592 |               bestWidth = width; | 
 | 1593 |               break; | 
| Dale Johannesen | 89217a6 | 2008-11-07 01:28:02 +0000 | [diff] [blame] | 1594 |             } | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1595 |             newMask = newMask << width; | 
| Dale Johannesen | 89217a6 | 2008-11-07 01:28:02 +0000 | [diff] [blame] | 1596 |           } | 
 | 1597 |         } | 
 | 1598 |       } | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1599 |       if (bestWidth) { | 
 | 1600 |         MVT newVT = MVT::getIntegerVT(bestWidth); | 
 | 1601 |         if (newVT.isRound()) { | 
 | 1602 |           MVT PtrType = Lod->getOperand(1).getValueType(); | 
 | 1603 |           SDValue Ptr = Lod->getBasePtr(); | 
 | 1604 |           if (bestOffset != 0) | 
 | 1605 |             Ptr = DAG.getNode(ISD::ADD, dl, PtrType, Lod->getBasePtr(), | 
 | 1606 |                               DAG.getConstant(bestOffset, PtrType)); | 
 | 1607 |           unsigned NewAlign = MinAlign(Lod->getAlignment(), bestOffset); | 
 | 1608 |           SDValue NewLoad = DAG.getLoad(newVT, dl, Lod->getChain(), Ptr, | 
 | 1609 |                                         Lod->getSrcValue(),  | 
 | 1610 |                                         Lod->getSrcValueOffset() + bestOffset, | 
 | 1611 |                                         false, NewAlign); | 
 | 1612 |           return DAG.getSetCC(dl, VT,  | 
 | 1613 |                               DAG.getNode(ISD::AND, dl, newVT, NewLoad, | 
 | 1614 |                                           DAG.getConstant(bestMask, newVT)), | 
 | 1615 |                               DAG.getConstant(0LL, newVT), Cond); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1616 |         } | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1617 |       } | 
 | 1618 |     } | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1619 |  | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1620 |     // If the LHS is a ZERO_EXTEND, perform the comparison on the input. | 
 | 1621 |     if (N0.getOpcode() == ISD::ZERO_EXTEND) { | 
 | 1622 |       unsigned InSize = N0.getOperand(0).getValueType().getSizeInBits(); | 
 | 1623 |  | 
 | 1624 |       // If the comparison constant has bits in the upper part, the | 
 | 1625 |       // zero-extended value could never match. | 
 | 1626 |       if (C1.intersects(APInt::getHighBitsSet(C1.getBitWidth(), | 
 | 1627 |                                               C1.getBitWidth() - InSize))) { | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1628 |         switch (Cond) { | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1629 |         case ISD::SETUGT: | 
 | 1630 |         case ISD::SETUGE: | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1631 |         case ISD::SETEQ: return DAG.getConstant(0, VT); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1632 |         case ISD::SETULT: | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1633 |         case ISD::SETULE: | 
 | 1634 |         case ISD::SETNE: return DAG.getConstant(1, VT); | 
 | 1635 |         case ISD::SETGT: | 
 | 1636 |         case ISD::SETGE: | 
 | 1637 |           // True if the sign bit of C1 is set. | 
 | 1638 |           return DAG.getConstant(C1.isNegative(), VT); | 
 | 1639 |         case ISD::SETLT: | 
 | 1640 |         case ISD::SETLE: | 
 | 1641 |           // True if the sign bit of C1 isn't set. | 
 | 1642 |           return DAG.getConstant(C1.isNonNegative(), VT); | 
 | 1643 |         default: | 
| Jakob Stoklund Olesen | 78d1264 | 2009-07-24 18:22:59 +0000 | [diff] [blame] | 1644 |           break; | 
 | 1645 |         } | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1646 |       } | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1647 |  | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1648 |       // Otherwise, we can perform the comparison with the low bits. | 
 | 1649 |       switch (Cond) { | 
 | 1650 |       case ISD::SETEQ: | 
 | 1651 |       case ISD::SETNE: | 
 | 1652 |       case ISD::SETUGT: | 
 | 1653 |       case ISD::SETUGE: | 
 | 1654 |       case ISD::SETULT: | 
 | 1655 |       case ISD::SETULE: { | 
 | 1656 |         MVT newVT = N0.getOperand(0).getValueType(); | 
 | 1657 |         if (DCI.isBeforeLegalizeOps() || | 
 | 1658 |             (isOperationLegal(ISD::SETCC, newVT) && | 
 | 1659 |               getCondCodeAction(Cond, newVT)==Legal)) | 
 | 1660 |           return DAG.getSetCC(dl, VT, N0.getOperand(0), | 
 | 1661 |                               DAG.getConstant(APInt(C1).trunc(InSize), newVT), | 
 | 1662 |                               Cond); | 
 | 1663 |         break; | 
 | 1664 |       } | 
 | 1665 |       default: | 
 | 1666 |         break;   // todo, be more careful with signed comparisons | 
 | 1667 |       } | 
 | 1668 |     } else if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG && | 
 | 1669 |                 (Cond == ISD::SETEQ || Cond == ISD::SETNE)) { | 
 | 1670 |       MVT ExtSrcTy = cast<VTSDNode>(N0.getOperand(1))->getVT(); | 
 | 1671 |       unsigned ExtSrcTyBits = ExtSrcTy.getSizeInBits(); | 
 | 1672 |       MVT ExtDstTy = N0.getValueType(); | 
 | 1673 |       unsigned ExtDstTyBits = ExtDstTy.getSizeInBits(); | 
 | 1674 |  | 
 | 1675 |       // If the extended part has any inconsistent bits, it cannot ever | 
 | 1676 |       // compare equal.  In other words, they have to be all ones or all | 
 | 1677 |       // zeros. | 
 | 1678 |       APInt ExtBits = | 
 | 1679 |         APInt::getHighBitsSet(ExtDstTyBits, ExtDstTyBits - ExtSrcTyBits); | 
 | 1680 |       if ((C1 & ExtBits) != 0 && (C1 & ExtBits) != ExtBits) | 
 | 1681 |         return DAG.getConstant(Cond == ISD::SETNE, VT); | 
 | 1682 |        | 
 | 1683 |       SDValue ZextOp; | 
 | 1684 |       MVT Op0Ty = N0.getOperand(0).getValueType(); | 
 | 1685 |       if (Op0Ty == ExtSrcTy) { | 
 | 1686 |         ZextOp = N0.getOperand(0); | 
 | 1687 |       } else { | 
 | 1688 |         APInt Imm = APInt::getLowBitsSet(ExtDstTyBits, ExtSrcTyBits); | 
 | 1689 |         ZextOp = DAG.getNode(ISD::AND, dl, Op0Ty, N0.getOperand(0), | 
 | 1690 |                               DAG.getConstant(Imm, Op0Ty)); | 
 | 1691 |       } | 
 | 1692 |       if (!DCI.isCalledByLegalizer()) | 
 | 1693 |         DCI.AddToWorklist(ZextOp.getNode()); | 
 | 1694 |       // Otherwise, make this a use of a zext. | 
 | 1695 |       return DAG.getSetCC(dl, VT, ZextOp,  | 
 | 1696 |                           DAG.getConstant(C1 & APInt::getLowBitsSet( | 
 | 1697 |                                                               ExtDstTyBits, | 
 | 1698 |                                                               ExtSrcTyBits),  | 
 | 1699 |                                           ExtDstTy), | 
 | 1700 |                           Cond); | 
 | 1701 |     } else if ((N1C->isNullValue() || N1C->getAPIntValue() == 1) && | 
 | 1702 |                 (Cond == ISD::SETEQ || Cond == ISD::SETNE)) { | 
 | 1703 |        | 
 | 1704 |       // SETCC (SETCC), [0|1], [EQ|NE]  -> SETCC | 
 | 1705 |       if (N0.getOpcode() == ISD::SETCC) { | 
 | 1706 |         bool TrueWhenTrue = (Cond == ISD::SETEQ) ^ (N1C->getZExtValue() != 1); | 
 | 1707 |         if (TrueWhenTrue) | 
 | 1708 |           return N0; | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1709 |          | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1710 |         // Invert the condition. | 
 | 1711 |         ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get(); | 
 | 1712 |         CC = ISD::getSetCCInverse(CC,  | 
 | 1713 |                                   N0.getOperand(0).getValueType().isInteger()); | 
 | 1714 |         return DAG.getSetCC(dl, VT, N0.getOperand(0), N0.getOperand(1), CC); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1715 |       } | 
 | 1716 |        | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1717 |       if ((N0.getOpcode() == ISD::XOR || | 
 | 1718 |             (N0.getOpcode() == ISD::AND &&  | 
 | 1719 |             N0.getOperand(0).getOpcode() == ISD::XOR && | 
 | 1720 |             N0.getOperand(1) == N0.getOperand(0).getOperand(1))) && | 
 | 1721 |           isa<ConstantSDNode>(N0.getOperand(1)) && | 
 | 1722 |           cast<ConstantSDNode>(N0.getOperand(1))->getAPIntValue() == 1) { | 
 | 1723 |         // If this is (X^1) == 0/1, swap the RHS and eliminate the xor.  We | 
 | 1724 |         // can only do this if the top bits are known zero. | 
 | 1725 |         unsigned BitWidth = N0.getValueSizeInBits(); | 
 | 1726 |         if (DAG.MaskedValueIsZero(N0, | 
 | 1727 |                                   APInt::getHighBitsSet(BitWidth, | 
 | 1728 |                                                         BitWidth-1))) { | 
 | 1729 |           // Okay, get the un-inverted input value. | 
 | 1730 |           SDValue Val; | 
 | 1731 |           if (N0.getOpcode() == ISD::XOR) | 
 | 1732 |             Val = N0.getOperand(0); | 
 | 1733 |           else { | 
 | 1734 |             assert(N0.getOpcode() == ISD::AND &&  | 
 | 1735 |                     N0.getOperand(0).getOpcode() == ISD::XOR); | 
 | 1736 |             // ((X^1)&1)^1 -> X & 1 | 
 | 1737 |             Val = DAG.getNode(ISD::AND, dl, N0.getValueType(), | 
 | 1738 |                               N0.getOperand(0).getOperand(0), | 
 | 1739 |                               N0.getOperand(1)); | 
 | 1740 |           } | 
 | 1741 |           return DAG.getSetCC(dl, VT, Val, N1, | 
 | 1742 |                               Cond == ISD::SETEQ ? ISD::SETNE : ISD::SETEQ); | 
 | 1743 |         } | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1744 |       } | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1745 |     } | 
 | 1746 |      | 
 | 1747 |     APInt MinVal, MaxVal; | 
 | 1748 |     unsigned OperandBitSize = N1C->getValueType(0).getSizeInBits(); | 
 | 1749 |     if (ISD::isSignedIntSetCC(Cond)) { | 
 | 1750 |       MinVal = APInt::getSignedMinValue(OperandBitSize); | 
 | 1751 |       MaxVal = APInt::getSignedMaxValue(OperandBitSize); | 
 | 1752 |     } else { | 
 | 1753 |       MinVal = APInt::getMinValue(OperandBitSize); | 
 | 1754 |       MaxVal = APInt::getMaxValue(OperandBitSize); | 
 | 1755 |     } | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1756 |  | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1757 |     // Canonicalize GE/LE comparisons to use GT/LT comparisons. | 
 | 1758 |     if (Cond == ISD::SETGE || Cond == ISD::SETUGE) { | 
 | 1759 |       if (C1 == MinVal) return DAG.getConstant(1, VT);   // X >= MIN --> true | 
 | 1760 |       // X >= C0 --> X > (C0-1) | 
 | 1761 |       return DAG.getSetCC(dl, VT, N0,  | 
 | 1762 |                           DAG.getConstant(C1-1, N1.getValueType()), | 
 | 1763 |                           (Cond == ISD::SETGE) ? ISD::SETGT : ISD::SETUGT); | 
 | 1764 |     } | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1765 |  | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1766 |     if (Cond == ISD::SETLE || Cond == ISD::SETULE) { | 
 | 1767 |       if (C1 == MaxVal) return DAG.getConstant(1, VT);   // X <= MAX --> true | 
 | 1768 |       // X <= C0 --> X < (C0+1) | 
 | 1769 |       return DAG.getSetCC(dl, VT, N0,  | 
 | 1770 |                           DAG.getConstant(C1+1, N1.getValueType()), | 
 | 1771 |                           (Cond == ISD::SETLE) ? ISD::SETLT : ISD::SETULT); | 
 | 1772 |     } | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1773 |  | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1774 |     if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MinVal) | 
 | 1775 |       return DAG.getConstant(0, VT);      // X < MIN --> false | 
 | 1776 |     if ((Cond == ISD::SETGE || Cond == ISD::SETUGE) && C1 == MinVal) | 
 | 1777 |       return DAG.getConstant(1, VT);      // X >= MIN --> true | 
 | 1778 |     if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C1 == MaxVal) | 
 | 1779 |       return DAG.getConstant(0, VT);      // X > MAX --> false | 
 | 1780 |     if ((Cond == ISD::SETLE || Cond == ISD::SETULE) && C1 == MaxVal) | 
 | 1781 |       return DAG.getConstant(1, VT);      // X <= MAX --> true | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1782 |  | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1783 |     // Canonicalize setgt X, Min --> setne X, Min | 
 | 1784 |     if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C1 == MinVal) | 
 | 1785 |       return DAG.getSetCC(dl, VT, N0, N1, ISD::SETNE); | 
 | 1786 |     // Canonicalize setlt X, Max --> setne X, Max | 
 | 1787 |     if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MaxVal) | 
 | 1788 |       return DAG.getSetCC(dl, VT, N0, N1, ISD::SETNE); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1789 |  | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1790 |     // If we have setult X, 1, turn it into seteq X, 0 | 
 | 1791 |     if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MinVal+1) | 
 | 1792 |       return DAG.getSetCC(dl, VT, N0,  | 
 | 1793 |                           DAG.getConstant(MinVal, N0.getValueType()),  | 
 | 1794 |                           ISD::SETEQ); | 
 | 1795 |     // If we have setugt X, Max-1, turn it into seteq X, Max | 
 | 1796 |     else if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C1 == MaxVal-1) | 
 | 1797 |       return DAG.getSetCC(dl, VT, N0,  | 
 | 1798 |                           DAG.getConstant(MaxVal, N0.getValueType()), | 
 | 1799 |                           ISD::SETEQ); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1800 |  | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1801 |     // If we have "setcc X, C0", check to see if we can shrink the immediate | 
 | 1802 |     // by changing cc. | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1803 |  | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1804 |     // SETUGT X, SINTMAX  -> SETLT X, 0 | 
 | 1805 |     if (Cond == ISD::SETUGT &&  | 
 | 1806 |         C1 == APInt::getSignedMaxValue(OperandBitSize)) | 
 | 1807 |       return DAG.getSetCC(dl, VT, N0,  | 
 | 1808 |                           DAG.getConstant(0, N1.getValueType()), | 
 | 1809 |                           ISD::SETLT); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1810 |  | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1811 |     // SETULT X, SINTMIN  -> SETGT X, -1 | 
 | 1812 |     if (Cond == ISD::SETULT && | 
 | 1813 |         C1 == APInt::getSignedMinValue(OperandBitSize)) { | 
 | 1814 |       SDValue ConstMinusOne = | 
 | 1815 |           DAG.getConstant(APInt::getAllOnesValue(OperandBitSize), | 
 | 1816 |                           N1.getValueType()); | 
 | 1817 |       return DAG.getSetCC(dl, VT, N0, ConstMinusOne, ISD::SETGT); | 
 | 1818 |     } | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1819 |  | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1820 |     // Fold bit comparisons when we can. | 
 | 1821 |     if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) && | 
 | 1822 |         VT == N0.getValueType() && N0.getOpcode() == ISD::AND) | 
 | 1823 |       if (ConstantSDNode *AndRHS = | 
 | 1824 |                   dyn_cast<ConstantSDNode>(N0.getOperand(1))) { | 
 | 1825 |         MVT ShiftTy = DCI.isBeforeLegalize() ? | 
 | 1826 |           getPointerTy() : getShiftAmountTy(); | 
 | 1827 |         if (Cond == ISD::SETNE && C1 == 0) {// (X & 8) != 0  -->  (X & 8) >> 3 | 
 | 1828 |           // Perform the xform if the AND RHS is a single bit. | 
 | 1829 |           if (isPowerOf2_64(AndRHS->getZExtValue())) { | 
 | 1830 |             return DAG.getNode(ISD::SRL, dl, VT, N0, | 
 | 1831 |                                 DAG.getConstant(Log2_64(AndRHS->getZExtValue()), | 
 | 1832 |                                                 ShiftTy)); | 
 | 1833 |           } | 
 | 1834 |         } else if (Cond == ISD::SETEQ && C1 == AndRHS->getZExtValue()) { | 
 | 1835 |           // (X & 8) == 8  -->  (X & 8) >> 3 | 
 | 1836 |           // Perform the xform if C1 is a single bit. | 
 | 1837 |           if (C1.isPowerOf2()) { | 
 | 1838 |             return DAG.getNode(ISD::SRL, dl, VT, N0, | 
 | 1839 |                                 DAG.getConstant(C1.logBase2(), ShiftTy)); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1840 |           } | 
 | 1841 |         } | 
| Eli Friedman | b101b0b | 2009-07-26 23:47:17 +0000 | [diff] [blame] | 1842 |       } | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1843 |   } | 
 | 1844 |  | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 1845 |   if (isa<ConstantFPSDNode>(N0.getNode())) { | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1846 |     // Constant fold or commute setcc. | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1847 |     SDValue O = DAG.FoldSetCC(VT, N0, N1, Cond, dl); | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 1848 |     if (O.getNode()) return O; | 
 | 1849 |   } else if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N1.getNode())) { | 
| Chris Lattner | 63079f0 | 2007-12-29 08:37:08 +0000 | [diff] [blame] | 1850 |     // If the RHS of an FP comparison is a constant, simplify it away in | 
 | 1851 |     // some cases. | 
 | 1852 |     if (CFP->getValueAPF().isNaN()) { | 
 | 1853 |       // If an operand is known to be a nan, we can fold it. | 
 | 1854 |       switch (ISD::getUnorderedFlavor(Cond)) { | 
| Torok Edwin | c23197a | 2009-07-14 16:55:14 +0000 | [diff] [blame] | 1855 |       default: llvm_unreachable("Unknown flavor!"); | 
| Chris Lattner | 63079f0 | 2007-12-29 08:37:08 +0000 | [diff] [blame] | 1856 |       case 0:  // Known false. | 
 | 1857 |         return DAG.getConstant(0, VT); | 
 | 1858 |       case 1:  // Known true. | 
 | 1859 |         return DAG.getConstant(1, VT); | 
| Chris Lattner | 1c3e1e2 | 2007-12-30 21:21:10 +0000 | [diff] [blame] | 1860 |       case 2:  // Undefined. | 
| Dale Johannesen | e8d7230 | 2009-02-06 23:05:02 +0000 | [diff] [blame] | 1861 |         return DAG.getUNDEF(VT); | 
| Chris Lattner | 63079f0 | 2007-12-29 08:37:08 +0000 | [diff] [blame] | 1862 |       } | 
 | 1863 |     } | 
 | 1864 |      | 
 | 1865 |     // Otherwise, we know the RHS is not a NaN.  Simplify the node to drop the | 
 | 1866 |     // constant if knowing that the operand is non-nan is enough.  We prefer to | 
 | 1867 |     // have SETO(x,x) instead of SETO(x, 0.0) because this avoids having to | 
 | 1868 |     // materialize 0.0. | 
 | 1869 |     if (Cond == ISD::SETO || Cond == ISD::SETUO) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1870 |       return DAG.getSetCC(dl, VT, N0, N0, Cond); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1871 |   } | 
 | 1872 |  | 
 | 1873 |   if (N0 == N1) { | 
 | 1874 |     // We can always fold X == X for integer setcc's. | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1875 |     if (N0.getValueType().isInteger()) | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1876 |       return DAG.getConstant(ISD::isTrueWhenEqual(Cond), VT); | 
 | 1877 |     unsigned UOF = ISD::getUnorderedFlavor(Cond); | 
 | 1878 |     if (UOF == 2)   // FP operators that are undefined on NaNs. | 
 | 1879 |       return DAG.getConstant(ISD::isTrueWhenEqual(Cond), VT); | 
 | 1880 |     if (UOF == unsigned(ISD::isTrueWhenEqual(Cond))) | 
 | 1881 |       return DAG.getConstant(UOF, VT); | 
 | 1882 |     // Otherwise, we can't fold it.  However, we can simplify it to SETUO/SETO | 
 | 1883 |     // if it is not already. | 
 | 1884 |     ISD::CondCode NewCond = UOF == 0 ? ISD::SETO : ISD::SETUO; | 
 | 1885 |     if (NewCond != Cond) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1886 |       return DAG.getSetCC(dl, VT, N0, N1, NewCond); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1887 |   } | 
 | 1888 |  | 
 | 1889 |   if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) && | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 1890 |       N0.getValueType().isInteger()) { | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1891 |     if (N0.getOpcode() == ISD::ADD || N0.getOpcode() == ISD::SUB || | 
 | 1892 |         N0.getOpcode() == ISD::XOR) { | 
 | 1893 |       // Simplify (X+Y) == (X+Z) -->  Y == Z | 
 | 1894 |       if (N0.getOpcode() == N1.getOpcode()) { | 
 | 1895 |         if (N0.getOperand(0) == N1.getOperand(0)) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1896 |           return DAG.getSetCC(dl, VT, N0.getOperand(1), N1.getOperand(1), Cond); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1897 |         if (N0.getOperand(1) == N1.getOperand(1)) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1898 |           return DAG.getSetCC(dl, VT, N0.getOperand(0), N1.getOperand(0), Cond); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1899 |         if (DAG.isCommutativeBinOp(N0.getOpcode())) { | 
 | 1900 |           // If X op Y == Y op X, try other combinations. | 
 | 1901 |           if (N0.getOperand(0) == N1.getOperand(1)) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1902 |             return DAG.getSetCC(dl, VT, N0.getOperand(1), N1.getOperand(0),  | 
 | 1903 |                                 Cond); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1904 |           if (N0.getOperand(1) == N1.getOperand(0)) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1905 |             return DAG.getSetCC(dl, VT, N0.getOperand(0), N1.getOperand(1),  | 
 | 1906 |                                 Cond); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1907 |         } | 
 | 1908 |       } | 
 | 1909 |        | 
 | 1910 |       if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(N1)) { | 
 | 1911 |         if (ConstantSDNode *LHSR = dyn_cast<ConstantSDNode>(N0.getOperand(1))) { | 
 | 1912 |           // Turn (X+C1) == C2 --> X == C2-C1 | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 1913 |           if (N0.getOpcode() == ISD::ADD && N0.getNode()->hasOneUse()) { | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1914 |             return DAG.getSetCC(dl, VT, N0.getOperand(0), | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 1915 |                                 DAG.getConstant(RHSC->getAPIntValue()- | 
 | 1916 |                                                 LHSR->getAPIntValue(), | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1917 |                                 N0.getValueType()), Cond); | 
 | 1918 |           } | 
 | 1919 |            | 
 | 1920 |           // Turn (X^C1) == C2 into X == C1^C2 iff X&~C1 = 0. | 
 | 1921 |           if (N0.getOpcode() == ISD::XOR) | 
 | 1922 |             // If we know that all of the inverted bits are zero, don't bother | 
 | 1923 |             // performing the inversion. | 
| Dan Gohman | 2e68b6f | 2008-02-25 21:11:39 +0000 | [diff] [blame] | 1924 |             if (DAG.MaskedValueIsZero(N0.getOperand(0), ~LHSR->getAPIntValue())) | 
 | 1925 |               return | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1926 |                 DAG.getSetCC(dl, VT, N0.getOperand(0), | 
| Dan Gohman | 2e68b6f | 2008-02-25 21:11:39 +0000 | [diff] [blame] | 1927 |                              DAG.getConstant(LHSR->getAPIntValue() ^ | 
 | 1928 |                                                RHSC->getAPIntValue(), | 
 | 1929 |                                              N0.getValueType()), | 
 | 1930 |                              Cond); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1931 |         } | 
 | 1932 |          | 
 | 1933 |         // Turn (C1-X) == C2 --> X == C1-C2 | 
 | 1934 |         if (ConstantSDNode *SUBC = dyn_cast<ConstantSDNode>(N0.getOperand(0))) { | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 1935 |           if (N0.getOpcode() == ISD::SUB && N0.getNode()->hasOneUse()) { | 
| Dan Gohman | 2e68b6f | 2008-02-25 21:11:39 +0000 | [diff] [blame] | 1936 |             return | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1937 |               DAG.getSetCC(dl, VT, N0.getOperand(1), | 
| Dan Gohman | 2e68b6f | 2008-02-25 21:11:39 +0000 | [diff] [blame] | 1938 |                            DAG.getConstant(SUBC->getAPIntValue() - | 
 | 1939 |                                              RHSC->getAPIntValue(), | 
 | 1940 |                                            N0.getValueType()), | 
 | 1941 |                            Cond); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1942 |           } | 
 | 1943 |         }           | 
 | 1944 |       } | 
 | 1945 |  | 
 | 1946 |       // Simplify (X+Z) == X -->  Z == 0 | 
 | 1947 |       if (N0.getOperand(0) == N1) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1948 |         return DAG.getSetCC(dl, VT, N0.getOperand(1), | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1949 |                         DAG.getConstant(0, N0.getValueType()), Cond); | 
 | 1950 |       if (N0.getOperand(1) == N1) { | 
 | 1951 |         if (DAG.isCommutativeBinOp(N0.getOpcode())) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1952 |           return DAG.getSetCC(dl, VT, N0.getOperand(0), | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1953 |                           DAG.getConstant(0, N0.getValueType()), Cond); | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 1954 |         else if (N0.getNode()->hasOneUse()) { | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1955 |           assert(N0.getOpcode() == ISD::SUB && "Unexpected operation!"); | 
 | 1956 |           // (Z-X) == X  --> Z == X<<1 | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1957 |           SDValue SH = DAG.getNode(ISD::SHL, dl, N1.getValueType(), | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1958 |                                      N1,  | 
 | 1959 |                                      DAG.getConstant(1, getShiftAmountTy())); | 
 | 1960 |           if (!DCI.isCalledByLegalizer()) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 1961 |             DCI.AddToWorklist(SH.getNode()); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1962 |           return DAG.getSetCC(dl, VT, N0.getOperand(0), SH, Cond); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1963 |         } | 
 | 1964 |       } | 
 | 1965 |     } | 
 | 1966 |  | 
 | 1967 |     if (N1.getOpcode() == ISD::ADD || N1.getOpcode() == ISD::SUB || | 
 | 1968 |         N1.getOpcode() == ISD::XOR) { | 
 | 1969 |       // Simplify  X == (X+Z) -->  Z == 0 | 
 | 1970 |       if (N1.getOperand(0) == N0) { | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1971 |         return DAG.getSetCC(dl, VT, N1.getOperand(1), | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1972 |                         DAG.getConstant(0, N1.getValueType()), Cond); | 
 | 1973 |       } else if (N1.getOperand(1) == N0) { | 
 | 1974 |         if (DAG.isCommutativeBinOp(N1.getOpcode())) { | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1975 |           return DAG.getSetCC(dl, VT, N1.getOperand(0), | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1976 |                           DAG.getConstant(0, N1.getValueType()), Cond); | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 1977 |         } else if (N1.getNode()->hasOneUse()) { | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1978 |           assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!"); | 
 | 1979 |           // X == (Z-X)  --> X<<1 == Z | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1980 |           SDValue SH = DAG.getNode(ISD::SHL, dl, N1.getValueType(), N0,  | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1981 |                                      DAG.getConstant(1, getShiftAmountTy())); | 
 | 1982 |           if (!DCI.isCalledByLegalizer()) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 1983 |             DCI.AddToWorklist(SH.getNode()); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1984 |           return DAG.getSetCC(dl, VT, SH, N1.getOperand(0), Cond); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 1985 |         } | 
 | 1986 |       } | 
 | 1987 |     } | 
| Dan Gohman | e5af2d3 | 2009-01-29 01:59:02 +0000 | [diff] [blame] | 1988 |  | 
| Dan Gohman | 2c65c3d | 2009-01-29 16:18:12 +0000 | [diff] [blame] | 1989 |     // Simplify x&y == y to x&y != 0 if y has exactly one bit set. | 
| Dale Johannesen | 85b0ede | 2009-02-11 19:19:41 +0000 | [diff] [blame] | 1990 |     // Note that where y is variable and is known to have at most | 
 | 1991 |     // one bit set (for example, if it is z&1) we cannot do this; | 
 | 1992 |     // the expressions are not equivalent when y==0. | 
| Dan Gohman | e5af2d3 | 2009-01-29 01:59:02 +0000 | [diff] [blame] | 1993 |     if (N0.getOpcode() == ISD::AND) | 
 | 1994 |       if (N0.getOperand(0) == N1 || N0.getOperand(1) == N1) { | 
| Dale Johannesen | 85b0ede | 2009-02-11 19:19:41 +0000 | [diff] [blame] | 1995 |         if (ValueHasExactlyOneBitSet(N1, DAG)) { | 
| Dan Gohman | e5af2d3 | 2009-01-29 01:59:02 +0000 | [diff] [blame] | 1996 |           Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true); | 
 | 1997 |           SDValue Zero = DAG.getConstant(0, N1.getValueType()); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 1998 |           return DAG.getSetCC(dl, VT, N0, Zero, Cond); | 
| Dan Gohman | e5af2d3 | 2009-01-29 01:59:02 +0000 | [diff] [blame] | 1999 |         } | 
 | 2000 |       } | 
 | 2001 |     if (N1.getOpcode() == ISD::AND) | 
 | 2002 |       if (N1.getOperand(0) == N0 || N1.getOperand(1) == N0) { | 
| Dale Johannesen | 85b0ede | 2009-02-11 19:19:41 +0000 | [diff] [blame] | 2003 |         if (ValueHasExactlyOneBitSet(N0, DAG)) { | 
| Dan Gohman | e5af2d3 | 2009-01-29 01:59:02 +0000 | [diff] [blame] | 2004 |           Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true); | 
 | 2005 |           SDValue Zero = DAG.getConstant(0, N0.getValueType()); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2006 |           return DAG.getSetCC(dl, VT, N1, Zero, Cond); | 
| Dan Gohman | e5af2d3 | 2009-01-29 01:59:02 +0000 | [diff] [blame] | 2007 |         } | 
 | 2008 |       } | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2009 |   } | 
 | 2010 |  | 
 | 2011 |   // Fold away ALL boolean setcc's. | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2012 |   SDValue Temp; | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2013 |   if (N0.getValueType() == MVT::i1 && foldBooleans) { | 
 | 2014 |     switch (Cond) { | 
| Torok Edwin | c23197a | 2009-07-14 16:55:14 +0000 | [diff] [blame] | 2015 |     default: llvm_unreachable("Unknown integer setcc!"); | 
| Bob Wilson | 4c24546 | 2009-01-22 17:39:32 +0000 | [diff] [blame] | 2016 |     case ISD::SETEQ:  // X == Y  -> ~(X^Y) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2017 |       Temp = DAG.getNode(ISD::XOR, dl, MVT::i1, N0, N1); | 
 | 2018 |       N0 = DAG.getNOT(dl, Temp, MVT::i1); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2019 |       if (!DCI.isCalledByLegalizer()) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2020 |         DCI.AddToWorklist(Temp.getNode()); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2021 |       break; | 
 | 2022 |     case ISD::SETNE:  // X != Y   -->  (X^Y) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2023 |       N0 = DAG.getNode(ISD::XOR, dl, MVT::i1, N0, N1); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2024 |       break; | 
| Bob Wilson | 4c24546 | 2009-01-22 17:39:32 +0000 | [diff] [blame] | 2025 |     case ISD::SETGT:  // X >s Y   -->  X == 0 & Y == 1  -->  ~X & Y | 
 | 2026 |     case ISD::SETULT: // X <u Y   -->  X == 0 & Y == 1  -->  ~X & Y | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2027 |       Temp = DAG.getNOT(dl, N0, MVT::i1); | 
| Dale Johannesen | de06470 | 2009-02-06 21:50:26 +0000 | [diff] [blame] | 2028 |       N0 = DAG.getNode(ISD::AND, dl, MVT::i1, N1, Temp); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2029 |       if (!DCI.isCalledByLegalizer()) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2030 |         DCI.AddToWorklist(Temp.getNode()); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2031 |       break; | 
| Bob Wilson | 4c24546 | 2009-01-22 17:39:32 +0000 | [diff] [blame] | 2032 |     case ISD::SETLT:  // X <s Y   --> X == 1 & Y == 0  -->  ~Y & X | 
 | 2033 |     case ISD::SETUGT: // X >u Y   --> X == 1 & Y == 0  -->  ~Y & X | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2034 |       Temp = DAG.getNOT(dl, N1, MVT::i1); | 
 | 2035 |       N0 = DAG.getNode(ISD::AND, dl, MVT::i1, N0, Temp); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2036 |       if (!DCI.isCalledByLegalizer()) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2037 |         DCI.AddToWorklist(Temp.getNode()); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2038 |       break; | 
| Bob Wilson | 4c24546 | 2009-01-22 17:39:32 +0000 | [diff] [blame] | 2039 |     case ISD::SETULE: // X <=u Y  --> X == 0 | Y == 1  -->  ~X | Y | 
 | 2040 |     case ISD::SETGE:  // X >=s Y  --> X == 0 | Y == 1  -->  ~X | Y | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2041 |       Temp = DAG.getNOT(dl, N0, MVT::i1); | 
 | 2042 |       N0 = DAG.getNode(ISD::OR, dl, MVT::i1, N1, Temp); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2043 |       if (!DCI.isCalledByLegalizer()) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2044 |         DCI.AddToWorklist(Temp.getNode()); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2045 |       break; | 
| Bob Wilson | 4c24546 | 2009-01-22 17:39:32 +0000 | [diff] [blame] | 2046 |     case ISD::SETUGE: // X >=u Y  --> X == 1 | Y == 0  -->  ~Y | X | 
 | 2047 |     case ISD::SETLE:  // X <=s Y  --> X == 1 | Y == 0  -->  ~Y | X | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2048 |       Temp = DAG.getNOT(dl, N1, MVT::i1); | 
 | 2049 |       N0 = DAG.getNode(ISD::OR, dl, MVT::i1, N0, Temp); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2050 |       break; | 
 | 2051 |     } | 
 | 2052 |     if (VT != MVT::i1) { | 
 | 2053 |       if (!DCI.isCalledByLegalizer()) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2054 |         DCI.AddToWorklist(N0.getNode()); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2055 |       // FIXME: If running after legalize, we probably can't do this. | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2056 |       N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, VT, N0); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2057 |     } | 
 | 2058 |     return N0; | 
 | 2059 |   } | 
 | 2060 |  | 
 | 2061 |   // Could not fold it. | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2062 |   return SDValue(); | 
| Evan Cheng | fa1eb27 | 2007-02-08 22:13:59 +0000 | [diff] [blame] | 2063 | } | 
 | 2064 |  | 
| Evan Cheng | ad4196b | 2008-05-12 19:56:52 +0000 | [diff] [blame] | 2065 | /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the | 
 | 2066 | /// node is a GlobalAddress + offset. | 
 | 2067 | bool TargetLowering::isGAPlusOffset(SDNode *N, GlobalValue* &GA, | 
 | 2068 |                                     int64_t &Offset) const { | 
 | 2069 |   if (isa<GlobalAddressSDNode>(N)) { | 
| Dan Gohman | 9ea3f56 | 2008-06-09 22:05:52 +0000 | [diff] [blame] | 2070 |     GlobalAddressSDNode *GASD = cast<GlobalAddressSDNode>(N); | 
 | 2071 |     GA = GASD->getGlobal(); | 
 | 2072 |     Offset += GASD->getOffset(); | 
| Evan Cheng | ad4196b | 2008-05-12 19:56:52 +0000 | [diff] [blame] | 2073 |     return true; | 
 | 2074 |   } | 
 | 2075 |  | 
 | 2076 |   if (N->getOpcode() == ISD::ADD) { | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2077 |     SDValue N1 = N->getOperand(0); | 
 | 2078 |     SDValue N2 = N->getOperand(1); | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2079 |     if (isGAPlusOffset(N1.getNode(), GA, Offset)) { | 
| Evan Cheng | ad4196b | 2008-05-12 19:56:52 +0000 | [diff] [blame] | 2080 |       ConstantSDNode *V = dyn_cast<ConstantSDNode>(N2); | 
 | 2081 |       if (V) { | 
| Dan Gohman | 7810bfe | 2008-09-26 21:54:37 +0000 | [diff] [blame] | 2082 |         Offset += V->getSExtValue(); | 
| Evan Cheng | ad4196b | 2008-05-12 19:56:52 +0000 | [diff] [blame] | 2083 |         return true; | 
 | 2084 |       } | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2085 |     } else if (isGAPlusOffset(N2.getNode(), GA, Offset)) { | 
| Evan Cheng | ad4196b | 2008-05-12 19:56:52 +0000 | [diff] [blame] | 2086 |       ConstantSDNode *V = dyn_cast<ConstantSDNode>(N1); | 
 | 2087 |       if (V) { | 
| Dan Gohman | 7810bfe | 2008-09-26 21:54:37 +0000 | [diff] [blame] | 2088 |         Offset += V->getSExtValue(); | 
| Evan Cheng | ad4196b | 2008-05-12 19:56:52 +0000 | [diff] [blame] | 2089 |         return true; | 
 | 2090 |       } | 
 | 2091 |     } | 
 | 2092 |   } | 
 | 2093 |   return false; | 
 | 2094 | } | 
 | 2095 |  | 
 | 2096 |  | 
| Nate Begeman | abc0199 | 2009-06-05 21:37:30 +0000 | [diff] [blame] | 2097 | /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a  | 
 | 2098 | /// location that is 'Dist' units away from the location that the 'Base' load  | 
 | 2099 | /// is loading from. | 
 | 2100 | bool TargetLowering::isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base,  | 
 | 2101 |                                        unsigned Bytes, int Dist,  | 
| Evan Cheng | 9bfa03c | 2008-05-12 23:04:07 +0000 | [diff] [blame] | 2102 |                                        const MachineFrameInfo *MFI) const { | 
| Nate Begeman | abc0199 | 2009-06-05 21:37:30 +0000 | [diff] [blame] | 2103 |   if (LD->getChain() != Base->getChain()) | 
| Evan Cheng | ad4196b | 2008-05-12 19:56:52 +0000 | [diff] [blame] | 2104 |     return false; | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 2105 |   MVT VT = LD->getValueType(0); | 
 | 2106 |   if (VT.getSizeInBits() / 8 != Bytes) | 
| Evan Cheng | ad4196b | 2008-05-12 19:56:52 +0000 | [diff] [blame] | 2107 |     return false; | 
 | 2108 |  | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2109 |   SDValue Loc = LD->getOperand(1); | 
 | 2110 |   SDValue BaseLoc = Base->getOperand(1); | 
| Evan Cheng | ad4196b | 2008-05-12 19:56:52 +0000 | [diff] [blame] | 2111 |   if (Loc.getOpcode() == ISD::FrameIndex) { | 
 | 2112 |     if (BaseLoc.getOpcode() != ISD::FrameIndex) | 
 | 2113 |       return false; | 
 | 2114 |     int FI  = cast<FrameIndexSDNode>(Loc)->getIndex(); | 
 | 2115 |     int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex(); | 
 | 2116 |     int FS  = MFI->getObjectSize(FI); | 
 | 2117 |     int BFS = MFI->getObjectSize(BFI); | 
 | 2118 |     if (FS != BFS || FS != (int)Bytes) return false; | 
 | 2119 |     return MFI->getObjectOffset(FI) == (MFI->getObjectOffset(BFI) + Dist*Bytes); | 
 | 2120 |   } | 
| Nate Begeman | abc0199 | 2009-06-05 21:37:30 +0000 | [diff] [blame] | 2121 |   if (Loc.getOpcode() == ISD::ADD && Loc.getOperand(0) == BaseLoc) { | 
 | 2122 |     ConstantSDNode *V = dyn_cast<ConstantSDNode>(Loc.getOperand(1)); | 
 | 2123 |     if (V && (V->getSExtValue() == Dist*Bytes)) | 
 | 2124 |       return true; | 
 | 2125 |   } | 
| Evan Cheng | ad4196b | 2008-05-12 19:56:52 +0000 | [diff] [blame] | 2126 |  | 
 | 2127 |   GlobalValue *GV1 = NULL; | 
 | 2128 |   GlobalValue *GV2 = NULL; | 
 | 2129 |   int64_t Offset1 = 0; | 
 | 2130 |   int64_t Offset2 = 0; | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2131 |   bool isGA1 = isGAPlusOffset(Loc.getNode(), GV1, Offset1); | 
 | 2132 |   bool isGA2 = isGAPlusOffset(BaseLoc.getNode(), GV2, Offset2); | 
| Evan Cheng | ad4196b | 2008-05-12 19:56:52 +0000 | [diff] [blame] | 2133 |   if (isGA1 && isGA2 && GV1 == GV2) | 
 | 2134 |     return Offset1 == (Offset2 + Dist*Bytes); | 
 | 2135 |   return false; | 
 | 2136 | } | 
 | 2137 |  | 
 | 2138 |  | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2139 | SDValue TargetLowering:: | 
| Chris Lattner | 00ffed0 | 2006-03-01 04:52:55 +0000 | [diff] [blame] | 2140 | PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { | 
 | 2141 |   // Default implementation: no optimization. | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2142 |   return SDValue(); | 
| Chris Lattner | 00ffed0 | 2006-03-01 04:52:55 +0000 | [diff] [blame] | 2143 | } | 
 | 2144 |  | 
| Chris Lattner | eb8146b | 2006-02-04 02:13:02 +0000 | [diff] [blame] | 2145 | //===----------------------------------------------------------------------===// | 
 | 2146 | //  Inline Assembler Implementation Methods | 
 | 2147 | //===----------------------------------------------------------------------===// | 
 | 2148 |  | 
| Chris Lattner | 4376fea | 2008-04-27 00:09:47 +0000 | [diff] [blame] | 2149 |  | 
| Chris Lattner | eb8146b | 2006-02-04 02:13:02 +0000 | [diff] [blame] | 2150 | TargetLowering::ConstraintType | 
| Chris Lattner | 4234f57 | 2007-03-25 02:14:49 +0000 | [diff] [blame] | 2151 | TargetLowering::getConstraintType(const std::string &Constraint) const { | 
| Chris Lattner | eb8146b | 2006-02-04 02:13:02 +0000 | [diff] [blame] | 2152 |   // FIXME: lots more standard ones to handle. | 
| Chris Lattner | 4234f57 | 2007-03-25 02:14:49 +0000 | [diff] [blame] | 2153 |   if (Constraint.size() == 1) { | 
 | 2154 |     switch (Constraint[0]) { | 
 | 2155 |     default: break; | 
 | 2156 |     case 'r': return C_RegisterClass; | 
 | 2157 |     case 'm':    // memory | 
 | 2158 |     case 'o':    // offsetable | 
 | 2159 |     case 'V':    // not offsetable | 
 | 2160 |       return C_Memory; | 
 | 2161 |     case 'i':    // Simple Integer or Relocatable Constant | 
 | 2162 |     case 'n':    // Simple Integer | 
 | 2163 |     case 's':    // Relocatable Constant | 
| Chris Lattner | c13dd1c | 2007-03-25 04:35:41 +0000 | [diff] [blame] | 2164 |     case 'X':    // Allow ANY value. | 
| Chris Lattner | 4234f57 | 2007-03-25 02:14:49 +0000 | [diff] [blame] | 2165 |     case 'I':    // Target registers. | 
 | 2166 |     case 'J': | 
 | 2167 |     case 'K': | 
 | 2168 |     case 'L': | 
 | 2169 |     case 'M': | 
 | 2170 |     case 'N': | 
 | 2171 |     case 'O': | 
 | 2172 |     case 'P': | 
 | 2173 |       return C_Other; | 
 | 2174 |     } | 
| Chris Lattner | eb8146b | 2006-02-04 02:13:02 +0000 | [diff] [blame] | 2175 |   } | 
| Chris Lattner | 065421f | 2007-03-25 02:18:14 +0000 | [diff] [blame] | 2176 |    | 
 | 2177 |   if (Constraint.size() > 1 && Constraint[0] == '{' &&  | 
 | 2178 |       Constraint[Constraint.size()-1] == '}') | 
 | 2179 |     return C_Register; | 
| Chris Lattner | 4234f57 | 2007-03-25 02:14:49 +0000 | [diff] [blame] | 2180 |   return C_Unknown; | 
| Chris Lattner | eb8146b | 2006-02-04 02:13:02 +0000 | [diff] [blame] | 2181 | } | 
 | 2182 |  | 
| Dale Johannesen | ba2a0b9 | 2008-01-29 02:21:21 +0000 | [diff] [blame] | 2183 | /// LowerXConstraint - try to replace an X constraint, which matches anything, | 
 | 2184 | /// with another that has more specific requirements based on the type of the | 
 | 2185 | /// corresponding operand. | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 2186 | const char *TargetLowering::LowerXConstraint(MVT ConstraintVT) const{ | 
 | 2187 |   if (ConstraintVT.isInteger()) | 
| Chris Lattner | 5e76423 | 2008-04-26 23:02:14 +0000 | [diff] [blame] | 2188 |     return "r"; | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 2189 |   if (ConstraintVT.isFloatingPoint()) | 
| Chris Lattner | 5e76423 | 2008-04-26 23:02:14 +0000 | [diff] [blame] | 2190 |     return "f";      // works for many targets | 
 | 2191 |   return 0; | 
| Dale Johannesen | ba2a0b9 | 2008-01-29 02:21:21 +0000 | [diff] [blame] | 2192 | } | 
 | 2193 |  | 
| Chris Lattner | 48884cd | 2007-08-25 00:47:38 +0000 | [diff] [blame] | 2194 | /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops | 
 | 2195 | /// vector.  If it is invalid, don't add anything to Ops. | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2196 | void TargetLowering::LowerAsmOperandForConstraint(SDValue Op, | 
| Chris Lattner | 48884cd | 2007-08-25 00:47:38 +0000 | [diff] [blame] | 2197 |                                                   char ConstraintLetter, | 
| Evan Cheng | da43bcf | 2008-09-24 00:05:32 +0000 | [diff] [blame] | 2198 |                                                   bool hasMemory, | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2199 |                                                   std::vector<SDValue> &Ops, | 
| Chris Lattner | 5e76423 | 2008-04-26 23:02:14 +0000 | [diff] [blame] | 2200 |                                                   SelectionDAG &DAG) const { | 
| Chris Lattner | eb8146b | 2006-02-04 02:13:02 +0000 | [diff] [blame] | 2201 |   switch (ConstraintLetter) { | 
| Chris Lattner | 9ff6ee8 | 2007-02-17 06:00:35 +0000 | [diff] [blame] | 2202 |   default: break; | 
| Dale Johannesen | eb57ea7 | 2007-11-05 21:20:28 +0000 | [diff] [blame] | 2203 |   case 'X':     // Allows any operand; labels (basic block) use this. | 
 | 2204 |     if (Op.getOpcode() == ISD::BasicBlock) { | 
 | 2205 |       Ops.push_back(Op); | 
 | 2206 |       return; | 
 | 2207 |     } | 
 | 2208 |     // fall through | 
| Chris Lattner | eb8146b | 2006-02-04 02:13:02 +0000 | [diff] [blame] | 2209 |   case 'i':    // Simple Integer or Relocatable Constant | 
 | 2210 |   case 'n':    // Simple Integer | 
| Dale Johannesen | eb57ea7 | 2007-11-05 21:20:28 +0000 | [diff] [blame] | 2211 |   case 's': {  // Relocatable Constant | 
| Chris Lattner | 75c7d2b | 2007-05-03 16:54:34 +0000 | [diff] [blame] | 2212 |     // These operands are interested in values of the form (GV+C), where C may | 
 | 2213 |     // be folded in as an offset of GV, or it may be explicitly added.  Also, it | 
 | 2214 |     // is possible and fine if either GV or C are missing. | 
 | 2215 |     ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op); | 
 | 2216 |     GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op); | 
 | 2217 |      | 
 | 2218 |     // If we have "(add GV, C)", pull out GV/C | 
 | 2219 |     if (Op.getOpcode() == ISD::ADD) { | 
 | 2220 |       C = dyn_cast<ConstantSDNode>(Op.getOperand(1)); | 
 | 2221 |       GA = dyn_cast<GlobalAddressSDNode>(Op.getOperand(0)); | 
 | 2222 |       if (C == 0 || GA == 0) { | 
 | 2223 |         C = dyn_cast<ConstantSDNode>(Op.getOperand(0)); | 
 | 2224 |         GA = dyn_cast<GlobalAddressSDNode>(Op.getOperand(1)); | 
 | 2225 |       } | 
 | 2226 |       if (C == 0 || GA == 0) | 
 | 2227 |         C = 0, GA = 0; | 
 | 2228 |     } | 
 | 2229 |      | 
 | 2230 |     // If we find a valid operand, map to the TargetXXX version so that the | 
 | 2231 |     // value itself doesn't get selected. | 
 | 2232 |     if (GA) {   // Either &GV   or   &GV+C | 
 | 2233 |       if (ConstraintLetter != 'n') { | 
 | 2234 |         int64_t Offs = GA->getOffset(); | 
| Dan Gohman | f5aeb1a | 2008-09-12 16:56:44 +0000 | [diff] [blame] | 2235 |         if (C) Offs += C->getZExtValue(); | 
| Chris Lattner | 48884cd | 2007-08-25 00:47:38 +0000 | [diff] [blame] | 2236 |         Ops.push_back(DAG.getTargetGlobalAddress(GA->getGlobal(), | 
 | 2237 |                                                  Op.getValueType(), Offs)); | 
 | 2238 |         return; | 
| Chris Lattner | 75c7d2b | 2007-05-03 16:54:34 +0000 | [diff] [blame] | 2239 |       } | 
 | 2240 |     } | 
 | 2241 |     if (C) {   // just C, no GV. | 
| Chris Lattner | 9ff6ee8 | 2007-02-17 06:00:35 +0000 | [diff] [blame] | 2242 |       // Simple constants are not allowed for 's'. | 
| Chris Lattner | 48884cd | 2007-08-25 00:47:38 +0000 | [diff] [blame] | 2243 |       if (ConstraintLetter != 's') { | 
| Dale Johannesen | 78e3e52 | 2009-02-12 20:58:09 +0000 | [diff] [blame] | 2244 |         // gcc prints these as sign extended.  Sign extend value to 64 bits | 
 | 2245 |         // now; without this it would get ZExt'd later in | 
 | 2246 |         // ScheduleDAGSDNodes::EmitNode, which is very generic. | 
 | 2247 |         Ops.push_back(DAG.getTargetConstant(C->getAPIntValue().getSExtValue(), | 
 | 2248 |                                             MVT::i64)); | 
| Chris Lattner | 48884cd | 2007-08-25 00:47:38 +0000 | [diff] [blame] | 2249 |         return; | 
 | 2250 |       } | 
| Chris Lattner | 9ff6ee8 | 2007-02-17 06:00:35 +0000 | [diff] [blame] | 2251 |     } | 
| Chris Lattner | 9ff6ee8 | 2007-02-17 06:00:35 +0000 | [diff] [blame] | 2252 |     break; | 
| Chris Lattner | eb8146b | 2006-02-04 02:13:02 +0000 | [diff] [blame] | 2253 |   } | 
| Chris Lattner | 75c7d2b | 2007-05-03 16:54:34 +0000 | [diff] [blame] | 2254 |   } | 
| Chris Lattner | eb8146b | 2006-02-04 02:13:02 +0000 | [diff] [blame] | 2255 | } | 
 | 2256 |  | 
| Chris Lattner | 4ccb070 | 2006-01-26 20:37:03 +0000 | [diff] [blame] | 2257 | std::vector<unsigned> TargetLowering:: | 
| Chris Lattner | 1efa40f | 2006-02-22 00:56:39 +0000 | [diff] [blame] | 2258 | getRegClassForInlineAsmConstraint(const std::string &Constraint, | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 2259 |                                   MVT VT) const { | 
| Chris Lattner | 1efa40f | 2006-02-22 00:56:39 +0000 | [diff] [blame] | 2260 |   return std::vector<unsigned>(); | 
 | 2261 | } | 
 | 2262 |  | 
 | 2263 |  | 
 | 2264 | std::pair<unsigned, const TargetRegisterClass*> TargetLowering:: | 
| Chris Lattner | 4217ca8dc | 2006-02-21 23:11:00 +0000 | [diff] [blame] | 2265 | getRegForInlineAsmConstraint(const std::string &Constraint, | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 2266 |                              MVT VT) const { | 
| Chris Lattner | 1efa40f | 2006-02-22 00:56:39 +0000 | [diff] [blame] | 2267 |   if (Constraint[0] != '{') | 
 | 2268 |     return std::pair<unsigned, const TargetRegisterClass*>(0, 0); | 
| Chris Lattner | a55079a | 2006-02-01 01:29:47 +0000 | [diff] [blame] | 2269 |   assert(*(Constraint.end()-1) == '}' && "Not a brace enclosed constraint?"); | 
 | 2270 |  | 
 | 2271 |   // Remove the braces from around the name. | 
 | 2272 |   std::string RegName(Constraint.begin()+1, Constraint.end()-1); | 
| Chris Lattner | 1efa40f | 2006-02-22 00:56:39 +0000 | [diff] [blame] | 2273 |  | 
 | 2274 |   // Figure out which register class contains this reg. | 
| Dan Gohman | 6f0d024 | 2008-02-10 18:45:23 +0000 | [diff] [blame] | 2275 |   const TargetRegisterInfo *RI = TM.getRegisterInfo(); | 
 | 2276 |   for (TargetRegisterInfo::regclass_iterator RCI = RI->regclass_begin(), | 
| Chris Lattner | 1efa40f | 2006-02-22 00:56:39 +0000 | [diff] [blame] | 2277 |        E = RI->regclass_end(); RCI != E; ++RCI) { | 
 | 2278 |     const TargetRegisterClass *RC = *RCI; | 
| Chris Lattner | b3befd4 | 2006-02-22 23:00:51 +0000 | [diff] [blame] | 2279 |      | 
 | 2280 |     // If none of the the value types for this register class are valid, we  | 
 | 2281 |     // can't use it.  For example, 64-bit reg classes on 32-bit targets. | 
 | 2282 |     bool isLegal = false; | 
 | 2283 |     for (TargetRegisterClass::vt_iterator I = RC->vt_begin(), E = RC->vt_end(); | 
 | 2284 |          I != E; ++I) { | 
 | 2285 |       if (isTypeLegal(*I)) { | 
 | 2286 |         isLegal = true; | 
 | 2287 |         break; | 
 | 2288 |       } | 
 | 2289 |     } | 
 | 2290 |      | 
 | 2291 |     if (!isLegal) continue; | 
 | 2292 |      | 
| Chris Lattner | 1efa40f | 2006-02-22 00:56:39 +0000 | [diff] [blame] | 2293 |     for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end();  | 
 | 2294 |          I != E; ++I) { | 
| Bill Wendling | 74ab84c | 2008-02-26 21:11:01 +0000 | [diff] [blame] | 2295 |       if (StringsEqualNoCase(RegName, RI->get(*I).AsmName)) | 
| Chris Lattner | 1efa40f | 2006-02-22 00:56:39 +0000 | [diff] [blame] | 2296 |         return std::make_pair(*I, RC); | 
| Chris Lattner | 1efa40f | 2006-02-22 00:56:39 +0000 | [diff] [blame] | 2297 |     } | 
| Chris Lattner | 4ccb070 | 2006-01-26 20:37:03 +0000 | [diff] [blame] | 2298 |   } | 
| Chris Lattner | a55079a | 2006-02-01 01:29:47 +0000 | [diff] [blame] | 2299 |    | 
| Chris Lattner | 1efa40f | 2006-02-22 00:56:39 +0000 | [diff] [blame] | 2300 |   return std::pair<unsigned, const TargetRegisterClass*>(0, 0); | 
| Chris Lattner | 4ccb070 | 2006-01-26 20:37:03 +0000 | [diff] [blame] | 2301 | } | 
| Evan Cheng | 30b37b5 | 2006-03-13 23:18:16 +0000 | [diff] [blame] | 2302 |  | 
 | 2303 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 4376fea | 2008-04-27 00:09:47 +0000 | [diff] [blame] | 2304 | // Constraint Selection. | 
 | 2305 |  | 
| Chris Lattner | 6bdcda3 | 2008-10-17 16:47:46 +0000 | [diff] [blame] | 2306 | /// isMatchingInputConstraint - Return true of this is an input operand that is | 
 | 2307 | /// a matching constraint like "4". | 
 | 2308 | bool TargetLowering::AsmOperandInfo::isMatchingInputConstraint() const { | 
| Chris Lattner | 58f15c4 | 2008-10-17 16:21:11 +0000 | [diff] [blame] | 2309 |   assert(!ConstraintCode.empty() && "No known constraint!"); | 
 | 2310 |   return isdigit(ConstraintCode[0]); | 
 | 2311 | } | 
 | 2312 |  | 
 | 2313 | /// getMatchedOperand - If this is an input matching constraint, this method | 
 | 2314 | /// returns the output operand it matches. | 
 | 2315 | unsigned TargetLowering::AsmOperandInfo::getMatchedOperand() const { | 
 | 2316 |   assert(!ConstraintCode.empty() && "No known constraint!"); | 
 | 2317 |   return atoi(ConstraintCode.c_str()); | 
 | 2318 | } | 
 | 2319 |  | 
 | 2320 |  | 
| Chris Lattner | 4376fea | 2008-04-27 00:09:47 +0000 | [diff] [blame] | 2321 | /// getConstraintGenerality - Return an integer indicating how general CT | 
 | 2322 | /// is. | 
 | 2323 | static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT) { | 
 | 2324 |   switch (CT) { | 
| Torok Edwin | c23197a | 2009-07-14 16:55:14 +0000 | [diff] [blame] | 2325 |   default: llvm_unreachable("Unknown constraint type!"); | 
| Chris Lattner | 4376fea | 2008-04-27 00:09:47 +0000 | [diff] [blame] | 2326 |   case TargetLowering::C_Other: | 
 | 2327 |   case TargetLowering::C_Unknown: | 
 | 2328 |     return 0; | 
 | 2329 |   case TargetLowering::C_Register: | 
 | 2330 |     return 1; | 
 | 2331 |   case TargetLowering::C_RegisterClass: | 
 | 2332 |     return 2; | 
 | 2333 |   case TargetLowering::C_Memory: | 
 | 2334 |     return 3; | 
 | 2335 |   } | 
 | 2336 | } | 
 | 2337 |  | 
 | 2338 | /// ChooseConstraint - If there are multiple different constraints that we | 
 | 2339 | /// could pick for this operand (e.g. "imr") try to pick the 'best' one. | 
| Chris Lattner | 24e1a9d | 2008-04-27 01:49:46 +0000 | [diff] [blame] | 2340 | /// This is somewhat tricky: constraints fall into four classes: | 
| Chris Lattner | 4376fea | 2008-04-27 00:09:47 +0000 | [diff] [blame] | 2341 | ///    Other         -> immediates and magic values | 
 | 2342 | ///    Register      -> one specific register | 
 | 2343 | ///    RegisterClass -> a group of regs | 
 | 2344 | ///    Memory        -> memory | 
 | 2345 | /// Ideally, we would pick the most specific constraint possible: if we have | 
 | 2346 | /// something that fits into a register, we would pick it.  The problem here | 
 | 2347 | /// is that if we have something that could either be in a register or in | 
 | 2348 | /// memory that use of the register could cause selection of *other* | 
 | 2349 | /// operands to fail: they might only succeed if we pick memory.  Because of | 
 | 2350 | /// this the heuristic we use is: | 
 | 2351 | /// | 
 | 2352 | ///  1) If there is an 'other' constraint, and if the operand is valid for | 
 | 2353 | ///     that constraint, use it.  This makes us take advantage of 'i' | 
 | 2354 | ///     constraints when available. | 
 | 2355 | ///  2) Otherwise, pick the most general constraint present.  This prefers | 
 | 2356 | ///     'm' over 'r', for example. | 
 | 2357 | /// | 
 | 2358 | static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo, | 
| Evan Cheng | da43bcf | 2008-09-24 00:05:32 +0000 | [diff] [blame] | 2359 |                              bool hasMemory,  const TargetLowering &TLI, | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2360 |                              SDValue Op, SelectionDAG *DAG) { | 
| Chris Lattner | 4376fea | 2008-04-27 00:09:47 +0000 | [diff] [blame] | 2361 |   assert(OpInfo.Codes.size() > 1 && "Doesn't have multiple constraint options"); | 
 | 2362 |   unsigned BestIdx = 0; | 
 | 2363 |   TargetLowering::ConstraintType BestType = TargetLowering::C_Unknown; | 
 | 2364 |   int BestGenerality = -1; | 
 | 2365 |    | 
 | 2366 |   // Loop over the options, keeping track of the most general one. | 
 | 2367 |   for (unsigned i = 0, e = OpInfo.Codes.size(); i != e; ++i) { | 
 | 2368 |     TargetLowering::ConstraintType CType = | 
 | 2369 |       TLI.getConstraintType(OpInfo.Codes[i]); | 
 | 2370 |      | 
| Chris Lattner | 5a09690 | 2008-04-27 00:37:18 +0000 | [diff] [blame] | 2371 |     // If this is an 'other' constraint, see if the operand is valid for it. | 
 | 2372 |     // For example, on X86 we might have an 'rI' constraint.  If the operand | 
 | 2373 |     // is an integer in the range [0..31] we want to use I (saving a load | 
 | 2374 |     // of a register), otherwise we must use 'r'. | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2375 |     if (CType == TargetLowering::C_Other && Op.getNode()) { | 
| Chris Lattner | 5a09690 | 2008-04-27 00:37:18 +0000 | [diff] [blame] | 2376 |       assert(OpInfo.Codes[i].size() == 1 && | 
 | 2377 |              "Unhandled multi-letter 'other' constraint"); | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2378 |       std::vector<SDValue> ResultOps; | 
| Evan Cheng | da43bcf | 2008-09-24 00:05:32 +0000 | [diff] [blame] | 2379 |       TLI.LowerAsmOperandForConstraint(Op, OpInfo.Codes[i][0], hasMemory, | 
| Chris Lattner | 5a09690 | 2008-04-27 00:37:18 +0000 | [diff] [blame] | 2380 |                                        ResultOps, *DAG); | 
 | 2381 |       if (!ResultOps.empty()) { | 
 | 2382 |         BestType = CType; | 
 | 2383 |         BestIdx = i; | 
 | 2384 |         break; | 
 | 2385 |       } | 
 | 2386 |     } | 
 | 2387 |      | 
| Chris Lattner | 4376fea | 2008-04-27 00:09:47 +0000 | [diff] [blame] | 2388 |     // This constraint letter is more general than the previous one, use it. | 
 | 2389 |     int Generality = getConstraintGenerality(CType); | 
 | 2390 |     if (Generality > BestGenerality) { | 
 | 2391 |       BestType = CType; | 
 | 2392 |       BestIdx = i; | 
 | 2393 |       BestGenerality = Generality; | 
 | 2394 |     } | 
 | 2395 |   } | 
 | 2396 |    | 
 | 2397 |   OpInfo.ConstraintCode = OpInfo.Codes[BestIdx]; | 
 | 2398 |   OpInfo.ConstraintType = BestType; | 
 | 2399 | } | 
 | 2400 |  | 
 | 2401 | /// ComputeConstraintToUse - Determines the constraint code and constraint | 
 | 2402 | /// type to use for the specific AsmOperandInfo, setting | 
 | 2403 | /// OpInfo.ConstraintCode and OpInfo.ConstraintType. | 
| Chris Lattner | 5a09690 | 2008-04-27 00:37:18 +0000 | [diff] [blame] | 2404 | void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo, | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2405 |                                             SDValue Op,  | 
| Evan Cheng | da43bcf | 2008-09-24 00:05:32 +0000 | [diff] [blame] | 2406 |                                             bool hasMemory, | 
| Chris Lattner | 5a09690 | 2008-04-27 00:37:18 +0000 | [diff] [blame] | 2407 |                                             SelectionDAG *DAG) const { | 
| Chris Lattner | 4376fea | 2008-04-27 00:09:47 +0000 | [diff] [blame] | 2408 |   assert(!OpInfo.Codes.empty() && "Must have at least one constraint"); | 
 | 2409 |    | 
 | 2410 |   // Single-letter constraints ('r') are very common. | 
 | 2411 |   if (OpInfo.Codes.size() == 1) { | 
 | 2412 |     OpInfo.ConstraintCode = OpInfo.Codes[0]; | 
 | 2413 |     OpInfo.ConstraintType = getConstraintType(OpInfo.ConstraintCode); | 
 | 2414 |   } else { | 
| Evan Cheng | da43bcf | 2008-09-24 00:05:32 +0000 | [diff] [blame] | 2415 |     ChooseConstraint(OpInfo, hasMemory, *this, Op, DAG); | 
| Chris Lattner | 4376fea | 2008-04-27 00:09:47 +0000 | [diff] [blame] | 2416 |   } | 
 | 2417 |    | 
 | 2418 |   // 'X' matches anything. | 
 | 2419 |   if (OpInfo.ConstraintCode == "X" && OpInfo.CallOperandVal) { | 
 | 2420 |     // Labels and constants are handled elsewhere ('X' is the only thing | 
| Dale Johannesen | 8ea5ec6 | 2009-07-07 23:26:33 +0000 | [diff] [blame] | 2421 |     // that matches labels).  For Functions, the type here is the type of | 
| Dale Johannesen | 5339c55 | 2009-07-20 23:27:39 +0000 | [diff] [blame] | 2422 |     // the result, which is not what we want to look at; leave them alone. | 
 | 2423 |     Value *v = OpInfo.CallOperandVal; | 
| Dale Johannesen | 8ea5ec6 | 2009-07-07 23:26:33 +0000 | [diff] [blame] | 2424 |     if (isa<BasicBlock>(v) || isa<ConstantInt>(v) || isa<Function>(v)) { | 
 | 2425 |       OpInfo.CallOperandVal = v; | 
| Chris Lattner | 4376fea | 2008-04-27 00:09:47 +0000 | [diff] [blame] | 2426 |       return; | 
| Dale Johannesen | 8ea5ec6 | 2009-07-07 23:26:33 +0000 | [diff] [blame] | 2427 |     } | 
| Chris Lattner | 4376fea | 2008-04-27 00:09:47 +0000 | [diff] [blame] | 2428 |      | 
 | 2429 |     // Otherwise, try to resolve it to something we know about by looking at | 
 | 2430 |     // the actual operand type. | 
 | 2431 |     if (const char *Repl = LowerXConstraint(OpInfo.ConstraintVT)) { | 
 | 2432 |       OpInfo.ConstraintCode = Repl; | 
 | 2433 |       OpInfo.ConstraintType = getConstraintType(OpInfo.ConstraintCode); | 
 | 2434 |     } | 
 | 2435 |   } | 
 | 2436 | } | 
 | 2437 |  | 
 | 2438 | //===----------------------------------------------------------------------===// | 
| Evan Cheng | 30b37b5 | 2006-03-13 23:18:16 +0000 | [diff] [blame] | 2439 | //  Loop Strength Reduction hooks | 
 | 2440 | //===----------------------------------------------------------------------===// | 
 | 2441 |  | 
| Chris Lattner | 1436bb6 | 2007-03-30 23:14:50 +0000 | [diff] [blame] | 2442 | /// isLegalAddressingMode - Return true if the addressing mode represented | 
 | 2443 | /// by AM is legal for this target, for a load/store of the specified type. | 
 | 2444 | bool TargetLowering::isLegalAddressingMode(const AddrMode &AM,  | 
 | 2445 |                                            const Type *Ty) const { | 
 | 2446 |   // The default implementation of this implements a conservative RISCy, r+r and | 
 | 2447 |   // r+i addr mode. | 
 | 2448 |  | 
 | 2449 |   // Allows a sign-extended 16-bit immediate field. | 
 | 2450 |   if (AM.BaseOffs <= -(1LL << 16) || AM.BaseOffs >= (1LL << 16)-1) | 
 | 2451 |     return false; | 
 | 2452 |    | 
 | 2453 |   // No global is ever allowed as a base. | 
 | 2454 |   if (AM.BaseGV) | 
 | 2455 |     return false; | 
 | 2456 |    | 
 | 2457 |   // Only support r+r,  | 
 | 2458 |   switch (AM.Scale) { | 
 | 2459 |   case 0:  // "r+i" or just "i", depending on HasBaseReg. | 
 | 2460 |     break; | 
 | 2461 |   case 1: | 
 | 2462 |     if (AM.HasBaseReg && AM.BaseOffs)  // "r+r+i" is not allowed. | 
 | 2463 |       return false; | 
 | 2464 |     // Otherwise we have r+r or r+i. | 
 | 2465 |     break; | 
 | 2466 |   case 2: | 
 | 2467 |     if (AM.HasBaseReg || AM.BaseOffs)  // 2*r+r  or  2*r+i is not allowed. | 
 | 2468 |       return false; | 
 | 2469 |     // Allow 2*r as r+r. | 
 | 2470 |     break; | 
 | 2471 |   } | 
 | 2472 |    | 
 | 2473 |   return true; | 
 | 2474 | } | 
 | 2475 |  | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2476 | /// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant, | 
 | 2477 | /// return a DAG expression to select that will generate the same value by | 
 | 2478 | /// multiplying by a magic number.  See: | 
 | 2479 | /// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html> | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2480 | SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG,  | 
 | 2481 |                                   std::vector<SDNode*>* Created) const { | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 2482 |   MVT VT = N->getValueType(0); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2483 |   DebugLoc dl= N->getDebugLoc(); | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2484 |    | 
 | 2485 |   // Check to see if we can do this. | 
| Eli Friedman | fc69cb4 | 2008-11-30 06:35:39 +0000 | [diff] [blame] | 2486 |   // FIXME: We should be more aggressive here. | 
 | 2487 |   if (!isTypeLegal(VT)) | 
 | 2488 |     return SDValue(); | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2489 |    | 
| Eli Friedman | fc69cb4 | 2008-11-30 06:35:39 +0000 | [diff] [blame] | 2490 |   APInt d = cast<ConstantSDNode>(N->getOperand(1))->getAPIntValue(); | 
| Jay Foad | 4e5ea55 | 2009-04-30 10:15:35 +0000 | [diff] [blame] | 2491 |   APInt::ms magics = d.magic(); | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2492 |    | 
 | 2493 |   // Multiply the numerator (operand 0) by the magic value | 
| Eli Friedman | fc69cb4 | 2008-11-30 06:35:39 +0000 | [diff] [blame] | 2494 |   // FIXME: We should support doing a MUL in a wider type | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2495 |   SDValue Q; | 
| Dan Gohman | f560ffa | 2009-01-28 17:46:25 +0000 | [diff] [blame] | 2496 |   if (isOperationLegalOrCustom(ISD::MULHS, VT)) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2497 |     Q = DAG.getNode(ISD::MULHS, dl, VT, N->getOperand(0), | 
| Dan Gohman | 525178c | 2007-10-08 18:33:35 +0000 | [diff] [blame] | 2498 |                     DAG.getConstant(magics.m, VT)); | 
| Dan Gohman | f560ffa | 2009-01-28 17:46:25 +0000 | [diff] [blame] | 2499 |   else if (isOperationLegalOrCustom(ISD::SMUL_LOHI, VT)) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2500 |     Q = SDValue(DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(VT, VT), | 
| Dan Gohman | 525178c | 2007-10-08 18:33:35 +0000 | [diff] [blame] | 2501 |                               N->getOperand(0), | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2502 |                               DAG.getConstant(magics.m, VT)).getNode(), 1); | 
| Dan Gohman | 525178c | 2007-10-08 18:33:35 +0000 | [diff] [blame] | 2503 |   else | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2504 |     return SDValue();       // No mulhs or equvialent | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2505 |   // If d > 0 and m < 0, add the numerator | 
| Eli Friedman | fc69cb4 | 2008-11-30 06:35:39 +0000 | [diff] [blame] | 2506 |   if (d.isStrictlyPositive() && magics.m.isNegative()) {  | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2507 |     Q = DAG.getNode(ISD::ADD, dl, VT, Q, N->getOperand(0)); | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2508 |     if (Created) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2509 |       Created->push_back(Q.getNode()); | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2510 |   } | 
 | 2511 |   // If d < 0 and m > 0, subtract the numerator. | 
| Eli Friedman | fc69cb4 | 2008-11-30 06:35:39 +0000 | [diff] [blame] | 2512 |   if (d.isNegative() && magics.m.isStrictlyPositive()) { | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2513 |     Q = DAG.getNode(ISD::SUB, dl, VT, Q, N->getOperand(0)); | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2514 |     if (Created) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2515 |       Created->push_back(Q.getNode()); | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2516 |   } | 
 | 2517 |   // Shift right algebraic if shift value is nonzero | 
 | 2518 |   if (magics.s > 0) { | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2519 |     Q = DAG.getNode(ISD::SRA, dl, VT, Q,  | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2520 |                     DAG.getConstant(magics.s, getShiftAmountTy())); | 
 | 2521 |     if (Created) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2522 |       Created->push_back(Q.getNode()); | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2523 |   } | 
 | 2524 |   // Extract the sign bit and add it to the quotient | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2525 |   SDValue T = | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2526 |     DAG.getNode(ISD::SRL, dl, VT, Q, DAG.getConstant(VT.getSizeInBits()-1, | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2527 |                                                  getShiftAmountTy())); | 
 | 2528 |   if (Created) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2529 |     Created->push_back(T.getNode()); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2530 |   return DAG.getNode(ISD::ADD, dl, VT, Q, T); | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2531 | } | 
 | 2532 |  | 
 | 2533 | /// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant, | 
 | 2534 | /// return a DAG expression to select that will generate the same value by | 
 | 2535 | /// multiplying by a magic number.  See: | 
 | 2536 | /// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html> | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2537 | SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG, | 
 | 2538 |                                   std::vector<SDNode*>* Created) const { | 
| Duncan Sands | 83ec4b6 | 2008-06-06 12:08:01 +0000 | [diff] [blame] | 2539 |   MVT VT = N->getValueType(0); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2540 |   DebugLoc dl = N->getDebugLoc(); | 
| Eli Friedman | 201c977 | 2008-11-30 06:02:26 +0000 | [diff] [blame] | 2541 |  | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2542 |   // Check to see if we can do this. | 
| Eli Friedman | 201c977 | 2008-11-30 06:02:26 +0000 | [diff] [blame] | 2543 |   // FIXME: We should be more aggressive here. | 
 | 2544 |   if (!isTypeLegal(VT)) | 
 | 2545 |     return SDValue(); | 
 | 2546 |  | 
 | 2547 |   // FIXME: We should use a narrower constant when the upper | 
 | 2548 |   // bits are known to be zero. | 
 | 2549 |   ConstantSDNode *N1C = cast<ConstantSDNode>(N->getOperand(1)); | 
| Jay Foad | 4e5ea55 | 2009-04-30 10:15:35 +0000 | [diff] [blame] | 2550 |   APInt::mu magics = N1C->getAPIntValue().magicu(); | 
| Eli Friedman | 201c977 | 2008-11-30 06:02:26 +0000 | [diff] [blame] | 2551 |  | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2552 |   // Multiply the numerator (operand 0) by the magic value | 
| Eli Friedman | 201c977 | 2008-11-30 06:02:26 +0000 | [diff] [blame] | 2553 |   // FIXME: We should support doing a MUL in a wider type | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2554 |   SDValue Q; | 
| Dan Gohman | f560ffa | 2009-01-28 17:46:25 +0000 | [diff] [blame] | 2555 |   if (isOperationLegalOrCustom(ISD::MULHU, VT)) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2556 |     Q = DAG.getNode(ISD::MULHU, dl, VT, N->getOperand(0), | 
| Dan Gohman | 525178c | 2007-10-08 18:33:35 +0000 | [diff] [blame] | 2557 |                     DAG.getConstant(magics.m, VT)); | 
| Dan Gohman | f560ffa | 2009-01-28 17:46:25 +0000 | [diff] [blame] | 2558 |   else if (isOperationLegalOrCustom(ISD::UMUL_LOHI, VT)) | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2559 |     Q = SDValue(DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(VT, VT), | 
| Dan Gohman | 525178c | 2007-10-08 18:33:35 +0000 | [diff] [blame] | 2560 |                               N->getOperand(0), | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2561 |                               DAG.getConstant(magics.m, VT)).getNode(), 1); | 
| Dan Gohman | 525178c | 2007-10-08 18:33:35 +0000 | [diff] [blame] | 2562 |   else | 
| Dan Gohman | 475871a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 2563 |     return SDValue();       // No mulhu or equvialent | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2564 |   if (Created) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2565 |     Created->push_back(Q.getNode()); | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2566 |  | 
 | 2567 |   if (magics.a == 0) { | 
| Eli Friedman | 201c977 | 2008-11-30 06:02:26 +0000 | [diff] [blame] | 2568 |     assert(magics.s < N1C->getAPIntValue().getBitWidth() && | 
 | 2569 |            "We shouldn't generate an undefined shift!"); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2570 |     return DAG.getNode(ISD::SRL, dl, VT, Q,  | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2571 |                        DAG.getConstant(magics.s, getShiftAmountTy())); | 
 | 2572 |   } else { | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2573 |     SDValue NPQ = DAG.getNode(ISD::SUB, dl, VT, N->getOperand(0), Q); | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2574 |     if (Created) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2575 |       Created->push_back(NPQ.getNode()); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2576 |     NPQ = DAG.getNode(ISD::SRL, dl, VT, NPQ,  | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2577 |                       DAG.getConstant(1, getShiftAmountTy())); | 
 | 2578 |     if (Created) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2579 |       Created->push_back(NPQ.getNode()); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2580 |     NPQ = DAG.getNode(ISD::ADD, dl, VT, NPQ, Q); | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2581 |     if (Created) | 
| Gabor Greif | ba36cb5 | 2008-08-28 21:40:38 +0000 | [diff] [blame] | 2582 |       Created->push_back(NPQ.getNode()); | 
| Dale Johannesen | ff97d4f | 2009-02-03 00:47:48 +0000 | [diff] [blame] | 2583 |     return DAG.getNode(ISD::SRL, dl, VT, NPQ,  | 
| Andrew Lenharth | dae9cbe | 2006-05-16 17:42:15 +0000 | [diff] [blame] | 2584 |                        DAG.getConstant(magics.s-1, getShiftAmountTy())); | 
 | 2585 |   } | 
 | 2586 | } | 
| Arnold Schwaighofer | e75fd69 | 2009-03-28 08:33:27 +0000 | [diff] [blame] | 2587 |  | 
| Arnold Schwaighofer | 11ff978 | 2009-03-28 12:36:29 +0000 | [diff] [blame] | 2588 | /// IgnoreHarmlessInstructions - Ignore instructions between a CALL and RET | 
 | 2589 | /// node that don't prevent tail call optimization. | 
 | 2590 | static SDValue IgnoreHarmlessInstructions(SDValue node) { | 
 | 2591 |   // Found call return. | 
 | 2592 |   if (node.getOpcode() == ISD::CALL) return node; | 
 | 2593 |   // Ignore MERGE_VALUES. Will have at least one operand. | 
 | 2594 |   if (node.getOpcode() == ISD::MERGE_VALUES) | 
 | 2595 |     return IgnoreHarmlessInstructions(node.getOperand(0)); | 
 | 2596 |   // Ignore ANY_EXTEND node. | 
 | 2597 |   if (node.getOpcode() == ISD::ANY_EXTEND) | 
 | 2598 |     return IgnoreHarmlessInstructions(node.getOperand(0)); | 
 | 2599 |   if (node.getOpcode() == ISD::TRUNCATE) | 
 | 2600 |     return IgnoreHarmlessInstructions(node.getOperand(0)); | 
 | 2601 |   // Any other node type. | 
 | 2602 |   return node; | 
 | 2603 | }  | 
 | 2604 |  | 
 | 2605 | bool TargetLowering::CheckTailCallReturnConstraints(CallSDNode *TheCall, | 
 | 2606 |                                                     SDValue Ret) { | 
| Arnold Schwaighofer | e75fd69 | 2009-03-28 08:33:27 +0000 | [diff] [blame] | 2607 |   unsigned NumOps = Ret.getNumOperands(); | 
| Arnold Schwaighofer | 11ff978 | 2009-03-28 12:36:29 +0000 | [diff] [blame] | 2608 |   // ISD::CALL results:(value0, ..., valuen, chain) | 
 | 2609 |   // ISD::RET  operands:(chain, value0, flag0, ..., valuen, flagn) | 
 | 2610 |   // Value return: | 
 | 2611 |   // Check that operand of the RET node sources from the CALL node. The RET node | 
 | 2612 |   // has at least two operands. Operand 0 holds the chain. Operand 1 holds the | 
 | 2613 |   // value. | 
| Arnold Schwaighofer | 5d2c01e | 2009-06-15 14:43:36 +0000 | [diff] [blame] | 2614 |   // Also we need to check that there is no code in between the call and the | 
 | 2615 |   // return. Hence we also check that the incomming chain to the return sources | 
 | 2616 |   // from the outgoing chain of the call. | 
| Arnold Schwaighofer | 11ff978 | 2009-03-28 12:36:29 +0000 | [diff] [blame] | 2617 |   if (NumOps > 1 && | 
| Arnold Schwaighofer | 5d2c01e | 2009-06-15 14:43:36 +0000 | [diff] [blame] | 2618 |       IgnoreHarmlessInstructions(Ret.getOperand(1)) == SDValue(TheCall,0) && | 
 | 2619 |       Ret.getOperand(0) == SDValue(TheCall, TheCall->getNumValues()-1)) | 
| Arnold Schwaighofer | e75fd69 | 2009-03-28 08:33:27 +0000 | [diff] [blame] | 2620 |     return true; | 
| Arnold Schwaighofer | 11ff978 | 2009-03-28 12:36:29 +0000 | [diff] [blame] | 2621 |   // void return: The RET node  has the chain result value of the CALL node as | 
 | 2622 |   // input. | 
 | 2623 |   if (NumOps == 1 && | 
 | 2624 |       Ret.getOperand(0) == SDValue(TheCall, TheCall->getNumValues()-1)) | 
| Arnold Schwaighofer | e75fd69 | 2009-03-28 08:33:27 +0000 | [diff] [blame] | 2625 |     return true; | 
| Arnold Schwaighofer | 11ff978 | 2009-03-28 12:36:29 +0000 | [diff] [blame] | 2626 |  | 
| Arnold Schwaighofer | e75fd69 | 2009-03-28 08:33:27 +0000 | [diff] [blame] | 2627 |   return false; | 
 | 2628 | } |