Mercurial > projects > ldc
comparison gen/toir.cpp @ 1225:837f48560863
No need for temporary alloca's here, use a phi node instead.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Sun, 19 Apr 2009 19:28:10 +0200 |
parents | 50dc0db06238 |
children | 01909bd1132c |
comparison
equal
deleted
inserted
replaced
1224:919fafcc505c | 1225:837f48560863 |
---|---|
1826 DValue* AndAndExp::toElem(IRState* p) | 1826 DValue* AndAndExp::toElem(IRState* p) |
1827 { | 1827 { |
1828 Logger::print("AndAndExp::toElem: %s @ %s\n", toChars(), type->toChars()); | 1828 Logger::print("AndAndExp::toElem: %s @ %s\n", toChars(), type->toChars()); |
1829 LOG_SCOPE; | 1829 LOG_SCOPE; |
1830 | 1830 |
1831 // allocate a temporary for the final result. failed to come up with a better way :/ | |
1832 LLValue* resval = 0; | |
1833 resval = DtoAlloca(LLType::Int1Ty,"andandtmp"); | |
1834 | |
1835 DValue* u = e1->toElem(p); | 1831 DValue* u = e1->toElem(p); |
1836 | 1832 |
1837 llvm::BasicBlock* oldend = p->scopeend(); | 1833 llvm::BasicBlock* oldend = p->scopeend(); |
1838 llvm::BasicBlock* andand = llvm::BasicBlock::Create("andand", gIR->topfunc(), oldend); | 1834 llvm::BasicBlock* andand = llvm::BasicBlock::Create("andand", gIR->topfunc(), oldend); |
1839 llvm::BasicBlock* andandend = llvm::BasicBlock::Create("andandend", gIR->topfunc(), oldend); | 1835 llvm::BasicBlock* andandend = llvm::BasicBlock::Create("andandend", gIR->topfunc(), oldend); |
1840 | 1836 |
1841 LLValue* ubool = DtoCast(loc, u, Type::tbool)->getRVal(); | 1837 LLValue* ubool = DtoCast(loc, u, Type::tbool)->getRVal(); |
1842 DtoStore(ubool,resval); | 1838 |
1839 llvm::BasicBlock* oldblock = p->scopebb(); | |
1843 llvm::BranchInst::Create(andand,andandend,ubool,p->scopebb()); | 1840 llvm::BranchInst::Create(andand,andandend,ubool,p->scopebb()); |
1844 | 1841 |
1845 p->scope() = IRScope(andand, andandend); | 1842 p->scope() = IRScope(andand, andandend); |
1846 DValue* v = e2->toElem(p); | 1843 DValue* v = e2->toElem(p); |
1847 | 1844 |
1845 LLValue* vbool = 0; | |
1848 if (!v->isFunc() && v->getType() != Type::tvoid) | 1846 if (!v->isFunc() && v->getType() != Type::tvoid) |
1849 { | 1847 { |
1850 LLValue* vbool = DtoCast(loc, v, Type::tbool)->getRVal(); | 1848 vbool = DtoCast(loc, v, Type::tbool)->getRVal(); |
1851 LLValue* uandvbool = llvm::BinaryOperator::Create(llvm::BinaryOperator::And, ubool, vbool,"tmp",p->scopebb()); | 1849 } |
1852 DtoStore(uandvbool,resval); | 1850 |
1853 } | 1851 llvm::BasicBlock* newblock = p->scopebb(); |
1854 | |
1855 llvm::BranchInst::Create(andandend,p->scopebb()); | 1852 llvm::BranchInst::Create(andandend,p->scopebb()); |
1856 p->scope() = IRScope(andandend, oldend); | 1853 p->scope() = IRScope(andandend, oldend); |
1857 | 1854 |
1858 resval = DtoLoad(resval); | 1855 LLValue* resval = 0; |
1856 if (ubool == vbool || !vbool) { | |
1857 // No need to create a PHI node. | |
1858 resval = ubool; | |
1859 } else { | |
1860 llvm::PHINode* phi = p->ir->CreatePHI(LLType::Int1Ty, "andandval"); | |
1861 // If we jumped over evaluation of the right-hand side, | |
1862 // the result is false. Otherwise it's the value of the right-hand side. | |
1863 phi->addIncoming(LLConstantInt::getFalse(), oldblock); | |
1864 phi->addIncoming(vbool, newblock); | |
1865 resval = phi; | |
1866 } | |
1867 | |
1859 return new DImValue(type, resval); | 1868 return new DImValue(type, resval); |
1860 } | 1869 } |
1861 | 1870 |
1862 ////////////////////////////////////////////////////////////////////////////////////////// | 1871 ////////////////////////////////////////////////////////////////////////////////////////// |
1863 | 1872 |
1864 DValue* OrOrExp::toElem(IRState* p) | 1873 DValue* OrOrExp::toElem(IRState* p) |
1865 { | 1874 { |
1866 Logger::print("OrOrExp::toElem: %s @ %s\n", toChars(), type->toChars()); | 1875 Logger::print("OrOrExp::toElem: %s @ %s\n", toChars(), type->toChars()); |
1867 LOG_SCOPE; | 1876 LOG_SCOPE; |
1868 | |
1869 // allocate a temporary for the final result. failed to come up with a better way :/ | |
1870 LLValue* resval = 0; | |
1871 resval = DtoAlloca(LLType::Int1Ty,"orortmp"); | |
1872 | 1877 |
1873 DValue* u = e1->toElem(p); | 1878 DValue* u = e1->toElem(p); |
1874 | 1879 |
1875 llvm::BasicBlock* oldend = p->scopeend(); | 1880 llvm::BasicBlock* oldend = p->scopeend(); |
1876 llvm::BasicBlock* oror = llvm::BasicBlock::Create("oror", gIR->topfunc(), oldend); | 1881 llvm::BasicBlock* oror = llvm::BasicBlock::Create("oror", gIR->topfunc(), oldend); |
1877 llvm::BasicBlock* ororend = llvm::BasicBlock::Create("ororend", gIR->topfunc(), oldend); | 1882 llvm::BasicBlock* ororend = llvm::BasicBlock::Create("ororend", gIR->topfunc(), oldend); |
1878 | 1883 |
1879 LLValue* ubool = DtoCast(loc, u, Type::tbool)->getRVal(); | 1884 LLValue* ubool = DtoCast(loc, u, Type::tbool)->getRVal(); |
1880 DtoStore(ubool,resval); | 1885 |
1886 llvm::BasicBlock* oldblock = p->scopebb(); | |
1881 llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb()); | 1887 llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb()); |
1882 | 1888 |
1883 p->scope() = IRScope(oror, ororend); | 1889 p->scope() = IRScope(oror, ororend); |
1884 DValue* v = e2->toElem(p); | 1890 DValue* v = e2->toElem(p); |
1885 | 1891 |
1892 LLValue* vbool = 0; | |
1886 if (!v->isFunc() && v->getType() != Type::tvoid) | 1893 if (!v->isFunc() && v->getType() != Type::tvoid) |
1887 { | 1894 { |
1888 LLValue* vbool = DtoCast(loc, v, Type::tbool)->getRVal(); | 1895 vbool = DtoCast(loc, v, Type::tbool)->getRVal(); |
1889 DtoStore(vbool,resval); | 1896 } |
1890 } | 1897 |
1891 | 1898 llvm::BasicBlock* newblock = p->scopebb(); |
1892 llvm::BranchInst::Create(ororend,p->scopebb()); | 1899 llvm::BranchInst::Create(ororend,p->scopebb()); |
1893 p->scope() = IRScope(ororend, oldend); | 1900 p->scope() = IRScope(ororend, oldend); |
1894 | 1901 |
1895 resval = DtoLoad(resval); | 1902 LLValue* resval = 0; |
1903 if (ubool == vbool || !vbool) { | |
1904 // No need to create a PHI node. | |
1905 resval = ubool; | |
1906 } else { | |
1907 llvm::PHINode* phi = p->ir->CreatePHI(LLType::Int1Ty, "ororval"); | |
1908 // If we jumped over evaluation of the right-hand side, | |
1909 // the result is true. Otherwise, it's the value of the right-hand side. | |
1910 phi->addIncoming(LLConstantInt::getTrue(), oldblock); | |
1911 phi->addIncoming(vbool, newblock); | |
1912 resval = phi; | |
1913 } | |
1914 | |
1896 return new DImValue(type, resval); | 1915 return new DImValue(type, resval); |
1897 } | 1916 } |
1898 | 1917 |
1899 ////////////////////////////////////////////////////////////////////////////////////////// | 1918 ////////////////////////////////////////////////////////////////////////////////////////// |
1900 | 1919 |